node.js express + aws elb - 从http重定向到https无法正常工作

时间:2017-09-21 19:06:52

标签: node.js express amazon-elb

我知道这已经被问到并在这里得到了解答,但仍然没有解决方案对我有用。这是app.js:

   var express  = require('express');
   var app      = express();

   app.all(function(req, res, next){
           if((!req.secure) && (req.get('X-Forwarded-Proto') !== 'https'))
           {
                console.log (req.get('Host'));
                console.log("not secure");
                res.redirect('https://' + req.get('Host') + req.url);
           }
           else{
           console.log("secure");
           next();
          }
      }
   );

   app.use(express.static('./server/static/'));
   app.listen(8080);

我也尝试过使用app.use但它仍无效。 我们正在使用AWS ELB,以下是听众:

LB协议| LB港口|实例协议|实例端口

HTTPS | 443 | HTTP | 8080
HTTP | 80 | HTTP | 8080

正如其他帖子中所提到的,我在请求标头中看不到'x-forwarded-proto'。我相信已经正确配置了侦听器,因此它们应该包含“x-forwarded”标头,但事实并非如此。

当我尝试在没有https的情况下点击dns时,它不会被重定向到https。 但是,http和https网址都可以单独使用。

请帮我弄清楚我缺少的是什么,或者是否需要提供更多信息。

1 个答案:

答案 0 :(得分:5)

您可能想要同时检查X-Forwarded-Proto'和' x-forwarded-proto' (小写)。此外,请求在您的应用程序中永远不会是安全的,因此您还应该删除req.secure检查。最终的代码看起来应该是这样的:

function forceHttps(req, res, next) {
    const xfp =
    req.headers["X-Forwarded-Proto"] || req.headers["x-forwarded-proto"];
    if (xfp === "http") {
        const secureUrl = `https://${req.headers.hostname}${req.url}`;
        res.redirect(301, secureUrl);
    } else {
        next();
    }
}

我们将此代码用于Elastic Load Balancer后面的Express应用程序,它运行正常。如果您不想自己编写中间件,我们甚至创建了一个处理此问题的小型NPM包:

https://www.npmjs.com/package/@crystallize/elasticloadbalancer-express-force-https

安装

npm i --save @crystallize/elasticloadbalancer-express-force-https

用法

const express = require('express');
const forceHttps = require('@crystallize/elasticloadbalancer-express-force-https');
const server = express();
server.use(forceHttps());

我们的博文中有关此内容的更多信息: https://snowball.digital/blog/force-https-behind-elastic-load-balancer-on-a-nodejs-application