一尘不染

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

node.js

我正在AWS上运行节点/快速服务,并已在其前面部署了ELB。当我启动启用了SSL的ELB实例时,它适用于我点击的第一页,但之后切换到HTTP以进行每次服务器访问。

ELB上的路由规则终止SSL,并将其转发到正在侦听该节点的端口8080。

SSL终止解决方案可以很好地实现我的目的,但是如何使后续的服务器调用保持在HTTPS上?


阅读 245

收藏
2020-07-07

共1个答案

一尘不染

我遇到过相同的问题,但背景略有不同。我当时使用AWS Elastic Beanstalk部署Node.js /
Express应用程序,并且能够在其上安装SSL证书。

结果是我的应用程序可以通过http和https协议访问。负载均衡器的路由表如下所示:

(Load balancer) http 80 --> (Node instance) http 8080
(Load balancer) https 443 --> (Node instance) http 8080

因此,问题是仅在我的node.js应用程序上授权https连接,但是如果最初使用http完成连接,则启用重定向到https的功能。

因为在AWS负载均衡器之后,所有通信都是通过http完成的,因此像这样的全局重定向指令(在这种情况下,作为中间件)将创建一个无限重定向循环:

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

->只是因为指令(req.protocol !== '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)。

所以这个小的修改就成功了:

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();
});

希望对您有所帮助!

2020-07-07