在 App Engine 柔性环境自定义运行时强制使用 SSL
Force SSL on App Engine Flexible Environment Custom Runtime
我们是 运行 App Engine 灵活自定义运行时上的 Metabase 实例,带有基于 openjdk:8 的 Dockerfile。目前它允许访问 http://[metabase-project].appspot.com/ and https://[metabase-project].appspot.com/。我想通过将所有 http 流量重定向到 https 来强制使用 SSL。
Dockerfile 看起来像这样:
FROM openjdk:8
ADD https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 ./cloud_sql_proxy
ADD http://downloads.metabase.com/v0.21.1/metabase.jar ./metabase.jar
CMD ./cloud_sql_proxy -instances=$INSTANCE=tcp:$MB_DB_PORT -dir=/cloudsql & java -jar ./metabase.jar
我们的 app.yaml 看起来像:
service: metabase
runtime: custom
env: flex
在普通的 App Engine app.yaml 文件中,我想添加:
handlers:
- url: [something]
secure: always
但在自定义运行时中,我们无法访问这样的处理程序。有没有办法配置灵活运行时来为所有流量执行重定向?
App Engine Flex 根本不支持处理程序:
https://cloud.google.com/appengine/docs/flexible/java/upgrading#appyaml_changes
如果您需要 https:// 重定向,则需要在您的应用程序中进行。抱歉!
由于您的应用程序(app.yaml 中的env: flex
)运行 位于终止 SSL 连接的 nginx 反向代理之后,您需要检查 X-FORWARDED-PROTO
header 将是 http
或 https
。如果是 http
那么你可以做重定向。
这对我有用。在我的例子中,在 Cloud Sites App Engine 灵活环境中使用基于 Loopback 的 NodeJS 应用程序 运行。
创建中间件,例如server/middleware/https-redirect.js
,代码如下:
/**
* Create a middleware to redirect http requests to https
* @param {Object} options Options
* @returns {Function} The express middleware handler
*/
module.exports = function(options) {
options = options || {};
var httpsPort = options.httpsPort || 443;
return function(req, res, next) {
if (req.protocol != 'https' && process.env.NODE_ENV !== 'development') {
var parts = req.get('host').split(':');
var host = parts[0] || '127.0.0.1';
return res.redirect('https://' + host + ':' + httpsPort + req.url);
}
next();
};
};
(基于 post http://www.jonxie.com/blog/2014/11/12/setting-up-loopback-to-use-https-and-ssl-certificates/ 中的第 8 步,但修改为使用 req.protocol
而不是 req.secure
,也将仅在以下情况下重定向在开发模式下不 运行)
修改文件server/server.js
请求:
var httpsRedirect = require('./middleware/https-redirect');
然后,在引导行之后:
var httpsPort = app.get('https-port');
app.use(httpsRedirect({httpsPort: httpsPort}));
app.set('trust proxy', true)
设置app.set('trust proxy', true)
会让req.protocol读取X-Forwarded-Proto
header。
参考文献:
回答晚了,但为了做到这一点,我不得不付出很多努力。
我点击了提到以下代码的各种链接,
app.use(function(req, res, next) {
if(!req.secure) {
return res.redirect(['https://', req.get('Host'), req.url].join(''));
}
next();
});
这可能适用于其他云供应商。
但是在@zengabor 正确提到的 GCP 中,我们的应用程序将 运行 位于终止 SSL 连接的 nginx 反向代理之后,我们需要检查 X-FORWARDED-PROTO
这可以通过下面的代码,
app.use(function(req, res, next) {
if(req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
return res.redirect(['https://', req.get('Host'), req.url].join(''));
}
next();
});
只是在阅读@zengabor 的代码后添加我的答案,我不得不再次搜索如何实现它。以上是可以使用的现成代码。
使用以下代码
app.use (function (req, res, next) {
var schema = (req.headers['x-forwarded-proto'] || '').toLowerCase();
if (schema === 'https') {
next();
} else {
res.redirect('https://' + req.headers.host + req.url);
}
});
这是我使用的 Node.js Express 代码:
// set the env variable REQUIRE_HTTPS=1 to enable this middleware
.use(function(req, res, next) {
// Redirect HTTP to HTTPS
if (!process.env.REQUIRE_HTTPS) return next();
if (req.headers["x-forwarded-proto"] === "https") return next();
if (req.protocol === "https") return next();
res.redirect(301, `https://${req.hostname}${req.url}`);
})
将其作为您的 Express 应用中的第一个中间件。
此代码假定您使用标准端口 http/https,就像您在 AppEngine 上一样。
我们是 运行 App Engine 灵活自定义运行时上的 Metabase 实例,带有基于 openjdk:8 的 Dockerfile。目前它允许访问 http://[metabase-project].appspot.com/ and https://[metabase-project].appspot.com/。我想通过将所有 http 流量重定向到 https 来强制使用 SSL。
Dockerfile 看起来像这样:
FROM openjdk:8
ADD https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 ./cloud_sql_proxy
ADD http://downloads.metabase.com/v0.21.1/metabase.jar ./metabase.jar
CMD ./cloud_sql_proxy -instances=$INSTANCE=tcp:$MB_DB_PORT -dir=/cloudsql & java -jar ./metabase.jar
我们的 app.yaml 看起来像:
service: metabase
runtime: custom
env: flex
在普通的 App Engine app.yaml 文件中,我想添加:
handlers:
- url: [something]
secure: always
但在自定义运行时中,我们无法访问这样的处理程序。有没有办法配置灵活运行时来为所有流量执行重定向?
App Engine Flex 根本不支持处理程序: https://cloud.google.com/appengine/docs/flexible/java/upgrading#appyaml_changes
如果您需要 https:// 重定向,则需要在您的应用程序中进行。抱歉!
由于您的应用程序(app.yaml 中的env: flex
)运行 位于终止 SSL 连接的 nginx 反向代理之后,您需要检查 X-FORWARDED-PROTO
header 将是 http
或 https
。如果是 http
那么你可以做重定向。
这对我有用。在我的例子中,在 Cloud Sites App Engine 灵活环境中使用基于 Loopback 的 NodeJS 应用程序 运行。
创建中间件,例如
server/middleware/https-redirect.js
,代码如下:/** * Create a middleware to redirect http requests to https * @param {Object} options Options * @returns {Function} The express middleware handler */ module.exports = function(options) { options = options || {}; var httpsPort = options.httpsPort || 443; return function(req, res, next) { if (req.protocol != 'https' && process.env.NODE_ENV !== 'development') { var parts = req.get('host').split(':'); var host = parts[0] || '127.0.0.1'; return res.redirect('https://' + host + ':' + httpsPort + req.url); } next(); }; };
(基于 post http://www.jonxie.com/blog/2014/11/12/setting-up-loopback-to-use-https-and-ssl-certificates/ 中的第 8 步,但修改为使用
req.protocol
而不是req.secure
,也将仅在以下情况下重定向在开发模式下不 运行)修改文件
server/server.js
请求:var httpsRedirect = require('./middleware/https-redirect');
然后,在引导行之后:
var httpsPort = app.get('https-port'); app.use(httpsRedirect({httpsPort: httpsPort})); app.set('trust proxy', true)
设置app.set('trust proxy', true)
会让req.protocol读取X-Forwarded-Proto
header。
参考文献:
回答晚了,但为了做到这一点,我不得不付出很多努力。
我点击了提到以下代码的各种链接,
app.use(function(req, res, next) {
if(!req.secure) {
return res.redirect(['https://', req.get('Host'), req.url].join(''));
}
next();
});
这可能适用于其他云供应商。
但是在@zengabor 正确提到的 GCP 中,我们的应用程序将 运行 位于终止 SSL 连接的 nginx 反向代理之后,我们需要检查 X-FORWARDED-PROTO
这可以通过下面的代码,
app.use(function(req, res, next) {
if(req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
return res.redirect(['https://', req.get('Host'), req.url].join(''));
}
next();
});
只是在阅读@zengabor 的代码后添加我的答案,我不得不再次搜索如何实现它。以上是可以使用的现成代码。
使用以下代码
app.use (function (req, res, next) {
var schema = (req.headers['x-forwarded-proto'] || '').toLowerCase();
if (schema === 'https') {
next();
} else {
res.redirect('https://' + req.headers.host + req.url);
}
});
这是我使用的 Node.js Express 代码:
// set the env variable REQUIRE_HTTPS=1 to enable this middleware
.use(function(req, res, next) {
// Redirect HTTP to HTTPS
if (!process.env.REQUIRE_HTTPS) return next();
if (req.headers["x-forwarded-proto"] === "https") return next();
if (req.protocol === "https") return next();
res.redirect(301, `https://${req.hostname}${req.url}`);
})
将其作为您的 Express 应用中的第一个中间件。
此代码假定您使用标准端口 http/https,就像您在 AppEngine 上一样。