当 node.js/express.js 在 AWS 负载均衡器后面运行时如何强制它使用 HTTPS [英] How to force node.js/express.js to HTTPS when it is running behind an AWS load balancer
问题描述
我正在 AWS 上运行一个节点/快速服务,并在它前面部署了一个 ELB.当我启动一个启用了 SSL 的 ELB 实例时,它适用于我点击的第一页,但之后的每个服务器访问都切换到 HTTP.
I'm running a node/express service on AWS and have deployed an ELB in front of it. When I spin up an ELB instance with SSL enabled, it works for the first page I hit, but then switches over to HTTP for every server access after that.
ELB 上的路由规则终止 SSL 并转发到端口 8080 哪个节点正在侦听.
The routing rule on the ELB terminates the SSL and forwards to port 8080 which node is listening on.
SSL 终止解决方案可以很好地满足我的目的,但我如何才能在 HTTPS 上保持后续服务器调用?
The SSL termination solution will work fine for my purposes, but how can I keep subsequent server calls on HTTPS?
推荐答案
我遇到了同样的问题,但上下文略有不同.我正在使用 AWS Elastic Beanstalk 部署 Node.js/Express 应用程序,并且能够在其上安装 SSL 证书.
I have experienced the same issue, but in a slightly different context. I was deploying Node.js/Express application using the AWS Elastic Beanstalk and was able to install an SSL certificate on it.
这样做的结果是我的应用程序可以通过 http 和 https 协议访问.负载均衡器的路由表如下所示:
The result of this was that my application was accessible on both the http and https protocol. The routing table of the load balancer were looking like this :
(Load balancer) http 80 --> (Node instance) http 8080
(Load balancer) https 443 --> (Node instance) http 8080
所以问题是在我的 node.js 应用程序上只授权 https 连接,但如果最初使用 http 完成连接,则启用重定向到 https.
So the question was to authorize only https connection on my node.js app, but enabling redirection to https if the connection was done initialy using http.
因为在 AWS 负载均衡器后面,所有通信都是通过 http 完成的,像这样的全局重定向指令(在这种情况下作为中间件)会创建一个无限重定向循环:
Because behind the AWS load balancer, all the communication are done over http, a global redirection instruction (as a middleware in this case) like this one would create an infinite redirection loop:
app.use(function(req, res, next) {
if((!req.secure) && (req.protocol !== 'https')) {
res.redirect('https://' + req.get('Host') + req.url);
}
}
--> 只是因为指令 (req.protocol !== 'https'
) 总是正确的!
--> simply becaue the instruction (req.protocol !== 'https'
) would always be true!
来自这篇博文(http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html),结果是 AWS ELB 添加了一个您可以捕获 X-Forwarded-Proto 标头以了解负载均衡器之前使用的协议(http 或 https).
From this blog post (http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html), it turns out that the AWS ELB adds a X-Forwarded-Proto header that you can capture to know what was the protocol used before the load balancer (http or https).
所以这个小小的修改成功了:
So this small modification did the trick :
app.use(function(req, res, next) {
if((!req.secure) && (req.get('X-Forwarded-Proto') !== 'https')) {
res.redirect('https://' + req.get('Host') + req.url);
}
else
next();
});
希望对您有所帮助!
这篇关于当 node.js/express.js 在 AWS 负载均衡器后面运行时如何强制它使用 HTTPS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!