nginx需透传x-forwarded-proto并配置proxy_set_header x-forwarded-proto $scheme;后端须启用对应转发头解析(如spring boot设server.forward-headers-strategy);配合proxy_redirect修正重定向协议,并添加host头及underscores_in_headers on支持下划线header。

这个问题本质是后端没拿到用户真实访问协议,Nginx 默认不传递协议信息,Java(或 .NET、Spring Boot 等)只能读到它直连时看到的 HTTP,而不是用户实际用的 HTTPS。
必须在 Nginx 中透传 X-Forwarded-Proto
这是最关键的一步。在 location 块里、proxy_pass 之后添加:
proxy_set_header X-Forwarded-Proto $scheme;
注意:$scheme 是动态值,能自动适配 HTTP 或 HTTPS 入口;不要写死成 https,否则 HTTP 测试环境会出错。
后端要主动读取并信任这个 Header
仅传 Header 不够,后端代码或框架必须启用解析逻辑:
- Spring Boot:配置
server.forward-headers-strategy=framework(推荐),或=native(需配合 Tomcat 的RemoteIpValve) - .NET Core / ASP.NET:确保
UseForwardedHeaders()中间件已注册,并设置ForwardedHeadersOptions.ForwardedProtoHeaderName = "X-Forwarded-Proto" - Java Servlet(如 Tomcat):需在
web.xml或 Java 配置中启用RemoteIpFilter,并指定protocolHeader="x-forwarded-proto"
避免重定向跳回 HTTP 的兜底措施
即使 Header 传了、后端也读了,某些老框架或硬编码 redirect 仍可能拼出 http:// 地址。这时靠 Nginx 拦截修正:
- 加
proxy_redirect http://127.0.0.1:8080/ https://$host/;(假设后端地址是http://127.0.0.1:8080) - 更通用写法:
proxy_redirect ~^http://[^/]+(/.*)?$ https://$host$1;,匹配任意 HTTP 开头的 Location 并强制转 HTTPS - 务必把
proxy_redirect放在proxy_pass后面,且前缀要和后端返回的 Location 完全一致(含协议、主机、端口、末尾斜杠)
别漏掉 Host 头和下划线支持
Host 头错误会导致后端生成的 URL 域名或端口不对;带下划线的自定义 Header(如 X_Api_Key)默认被 Nginx 丢弃:
- 加
proxy_set_header Host $host;和proxy_set_header X-Forwarded-Host $host; - 在
http或server块顶部加underscores_in_headers on;,否则像X-Auth-Token这类头会消失











