我正在尝试为处理HTTPSredirect本身的应用程序设置一个反向代理(即,如果它注意到该协议不是HTTPS,它将把用户redirect到安全站点):
server { listen 80 default_server; listen 443 ssl; location / { proxy_pass http://localhost:8080; proxy_redirect default; proxy_redirect https://$proxy_host/ https://$host/; proxy_set_header X-Forwarded-Proto $scheme; } }
上游服务器需要通过X-Forwarded-Proto头来知道原始请求是否通过了https,它应该知道,假设$scheme在80上是“http”,在443上是“https”。
然而,对于443 和 80端口的请求,似乎总是将$scheme设置为“https”,将$https设置为“on” – 即使这些variables总是说连接是安全的,即使它不是这样? 这些variables是基于服务器configuration“硬编码”的,而不是实际的传入请求?
我的错。 nginx设置$scheme (大概$https ),如我所料,每个请求。
麻烦的是下面的node.js代码:
var proto = req.headers['x-forwarded-proto'] || (req.connection.encrypted) ? 'https' : 'http';
它看起来是正确的,但运算符的优先顺序实际上是错误的! 应该是这样的:
var proto = req.headers['x-forwarded-proto'] || ((req.connection.encrypted) ? 'https' : 'http');
如果没有修复,每当req.headers['x-forwarded-proto']出现时,即使nginx的头部是正确的,我的本地proto也会被设置为“https”!