Nginx透传客户端真实协议需设置X-Forwarded-Proto头,优先使用proxy_set_header X-Forwarded-Proto $scheme;确保后端正确解析该头以避免重定向循环等问题。

在 Nginx 中透传客户端的真实请求协议(HTTP 或 HTTPS),关键在于正确设置 X-Forwarded-Proto 请求头,尤其当 Nginx 作为反向代理部署在负载均衡器(如 AWS ALB、CDN、TLS 终结层)之后时。后端应用依赖该头部判断原始请求是否走 HTTPS,否则可能出现重定向循环、混合内容警告或登录态异常。
确认上游是否已提供协议信息
很多云服务(如阿里云 SLB、腾讯云 CLB、Cloudflare、AWS ALB)会在转发请求时自动添加 X-Forwarded-Proto 头。可通过日志或调试接口验证:
- 在 Nginx 配置中临时添加:
log_format debug_log '$http_x_forwarded_proto - $scheme $request';,并启用该日志格式 - 用
curl -H "X-Forwarded-Proto: https" http://your-domain/模拟测试 - 若上游已稳定传递,通常无需额外设置,直接透传即可
手动设置 X-Forwarded-Proto(推荐方式)
当上游未设置或不可信时,应由 Nginx 根据自身接收连接的协议主动注入。核心是用 $scheme 变量(值为 http 或 https)赋值给请求头:
- 在
location或server块中添加:proxy_set_header X-Forwarded-Proto $scheme; - 确保该指令出现在
proxy_pass之前,且未被其他同名指令覆盖 - 若 Nginx 同时监听 HTTP 和 HTTPS 端口,
$scheme会自动匹配当前连接协议,无需条件判断
避免协议头被重复或污染
多个代理层叠加时,X-Forwarded-Proto 可能被多次修改,导致后端取到错误值:
- 禁用从客户端直接传入的该头部(防伪造):
proxy_set_header X-Forwarded-Proto "";先清空,再用$scheme覆盖 - 若使用
real_ip_module并配置了可信代理 IP,可结合set_real_ip_from+real_ip_header X-Forwarded-For,但注意X-Forwarded-Proto不受 real_ip 模块影响,仍需手动控制 - 不建议用
map块根据$http_x_forwarded_proto动态赋值——易引入信任链漏洞
后端应用需正确读取该头部
Nginx 设置只是前提,后端框架必须主动解析 X-Forwarded-Proto 才生效:
- Spring Boot:启用
server.forward-headers-strategy=framework,并配置trusted-proxies - Node.js(Express):设
app.set('trust proxy', true),框架自动识别X-Forwarded-Proto - PHP(Laravel):需在
TrustProxies中配置可信代理 IP,并确保APP_URL不硬编码协议











