简体   繁体   English

如何在AWS负载均衡器后面运行时强制node.js / express.js为HTTPS

[英]How to force node.js/express.js to HTTPS when it is running behind an AWS load balancer

I'm running a node/express service on AWS and have deployed an ELB in front of it. 我正在AWS上运行节点/快速服务,并在其前面部署了一个ELB。 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. 当我启用启用了SSL的ELB实例时,它适用于我点击的第一个页面,但之后会为每个服务器访问切换到HTTP。

The routing rule on the ELB terminates the SSL and forwards to port 8080 which node is listening on. ELB上的路由规则终止SSL并转发到节点正在侦听的端口8080。

The SSL termination solution will work fine for my purposes, but how can I keep subsequent server calls on HTTPS? SSL终止解决方案适用于我的目的,但如何在HTTPS上保留后续服务器调用?

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. 我正在使用AWS Elastic Beanstalk部署Node.js / Express应用程序,并且能够在其上安装SSL证书。

The result of this was that my application was accessible on both the http and https protocol. 结果是我的应用程序可以在http和https协议上访问。 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

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. 所以问题是在我的node.js应用程序上仅授权https连接,但如果连接是使用http初始化完成,则启用重定向到https。

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: 因为在AWS负载均衡器后面,所有通信都是通过http完成的,全局重定向指令(在这种情况下作为中间件)就像这样会创建一个无限重定向循环:

app.use(function(req, res, next) {
    if((!req.secure) && (req.protocol !== 'https')) {
        res.redirect('https://' + req.get('Host') + req.url);
    }
}

--> simply becaue the instruction ( req.protocol !== 'https' ) would always be true! - >简单地说,指令( req.protocol !== '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). 从这篇博文( http://matthew.mceachen.us/blog/howto-force-https-with-amazon-elastic-load-balancer-and-apache-1071.html )中可以看出,AWS ELB添加了您可以捕获的X-Forwarded-Proto标头,以了解在负载均衡器(http或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();
});

Hope this help! 希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM