在使用EBS和ELB环境的Node.js Express应用中转发HTTP到HTTPS

6

我正在使用以下方法将所有http请求重定向到https请求。

从日志中可以看出,头信息“x-forwarded-proto”从未被填充并且为未定义状态。

app.get('*', function(req, res, next) {
    //http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
    if (req.headers['x-forwarded-proto'] != "https") {
        res.redirect('https://' + req.get('host') + req.url);
    } else {
        next();     
    }
});

这会导致重定向循环。如何在没有循环的情况下正确地进行重定向?

2个回答

10
编辑: 下面的原始答案适用于Express 3.x,对于4.x,您可以在req.protocol中获得一个字符串httphttps,感谢@BrandonClark。
请使用req.get而不是req.headers。请注意,POST请求和所有其他非GET请求将不会看到此中间件。 当您重定向时,Express可能无法携带x-forwarded-proto头文件。您可能需要自行设置它。
app.get('*', function(req, res, next) {
//http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
    if (req.get('x-forwarded-proto') != "https") {
        res.set('x-forwarded-proto', 'https');
        res.redirect('https://' + req.get('host') + req.url);
    } else {
        next();     
    }
});

强制使用https的另一种方法:

function ensureSecure(req, res, next){
  if(req.secure){
    // OK, continue
    return next();
  };
  res.redirect('https://'+req.host+req.url); // handle port numbers if non 443
};

app.all('*', ensureSecure);

1
第二种技术也不起作用,因为负载均衡器总是将http请求(req.secure始终为false)发送到应用程序。 - user883499
请更详细地解释一下你正在做什么。除了来自亚马逊弹性负载均衡器的请求之外,您是否还有其他请求?如果 ELB 正在向您的应用程序发出 HTTP 请求,并且您想要 HTTPS,那么您不能配置 ELB 发出 HTTPS 请求吗? - Plato
3
在 Express 4 中,你可以使用 req.protocol 来检测请求是通过 http 还是 https 发送的。 - Brandon Clark
1
AWS ELB和ALB的绝佳技巧 - Gaurav Rawat
1
我只能通过以下方式使其工作:router.use(function(req, res, next) { if (req.header('X-Forwarded-Proto') == 'https') next(); else res.redirect('https://' + req.host + req.url); }); 关于 X-Forwarded-Proto 标头的更多详细信息可以在此处找到:https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/ - DauleDK
显示剩余5条评论

1
您可以在EC2实例中编辑nginx配置文件。SSH到EC2实例并按照以下步骤操作:
  1. 进入 /etc/nginx/conf.d
  2. 打开 00_elastic_beanstalk_proxy.conf sudo vi 00_elastic_beanstalk_proxy.conf
  3. 添加

    location / { if ($http_x_forwarded_proto != 'https') { rewrite ^ https://$host$request_uri? permanent; } … }

  4. 重新加载nginx sudo /usr/sbin/nginx -s reload


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接