使用 EBS 和 ELB 环境在 node.js express 应用程序中将 http 转发到 https

Posted

技术标签:

【中文标题】使用 EBS 和 ELB 环境在 node.js express 应用程序中将 http 转发到 https【英文标题】:Forwarding http to https in node.js express app using EBS & ELB environment 【发布时间】:2013-10-03 11:34:29 【问题描述】:

我正在使用以下内容将所有 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();     
    
);

它导致了重定向循环。如何在不循环的情况下正确重定向?

【问题讨论】:

【参考方案1】:

编辑: 我在下面的原始答案是 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);

【讨论】:

试过你的建议还是不行。弹性负载均衡器未设置正确的标头。 res.set('x-forwarded-proto', 'https'); 也不行。 第二种技术也不起作用,因为负载均衡器总是向应用程序提供 http (req.secure always false) 请求。 表达4可以使用req.protocol检测httphttps AWS elb 和 alb 的重要提示 我只能通过执行以下操作router.use(function(req, res, next) if (req.header('X-Forwarded-Proto') == 'https') next(); else res.redirect('https://' + req.host + req.url); ); 来获得此功能 【参考方案2】:

您可以在 EC2 实例中编辑 nginx 配置文件。 SSH 到 ec2 实例并按照以下步骤操作

    转至/etc/nginx/conf.d 打开00_elastic_beanstalk_proxy.conf sudo vi 00_elastic_beanstalk_proxy.conf

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

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

【讨论】:

以上是关于使用 EBS 和 ELB 环境在 node.js express 应用程序中将 http 转发到 https的主要内容,如果未能解决你的问题,请参考以下文章

如何使 ELB 将协议传递给 node.js 进程(Elastic Beanstalk)

AWS ELB - 服务 A 无法连接到同一安全组中的服务 B

ECS 和应用负载均衡器

使用 EBS 部署多容器 docker 环境(flask 和 nginx)

使用 AWS(ELB、Kubernetes Nginx 和 ACM)配置 HSTS

从弹性beantalk上的docker-compose部署查看node.js日志(console.log)