必须设置proxy_set_header X-Forwarded-Proto $scheme;,并确保后端框架显式信任该头,否则后端会误判协议导致重定向错误、Secure Cookie 失效及绝对 URL 构建异常。

在 Nginx 做 SSL 卸载(即客户端 HTTPS → Nginx 解密 → 后端 HTTP)时,后端看到的始终是内部 HTTP 请求,若不显式告知原始协议,就会误判为 HTTP,导致重定向跳回 HTTP、Secure Cookie 被拒绝、密码重置链接用 http:// 等问题。核心解法就是用 proxy_set_header X-Forwarded-Proto $scheme 把真实协议透传过去,并确保后端可信地使用它。
必须在 Nginx 中正确设置该头
这一行不能省略,也不能写错:
- 放在
location或server块中,且必须位于proxy_pass指令之前 - 写成
proxy_set_header X-Forwarded-Proto $scheme;——$scheme是 Nginx 内置变量,自动取值http或https,取决于客户端实际连接协议 - 绝不能硬编码为
https,否则 HTTP 访问也会被标记为 HTTPS,引发 Cookie、CSRF、重定向逻辑错误 - 若同时监听 80 和 443 端口,两个 server 块都应包含该配置,Nginx 会各自按需填充
配套转发头建议一并设置
单靠 X-Forwarded-Proto 不足以还原完整请求上下文,推荐同步添加:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 支持多层代理,安全追加客户端 IP -
proxy_set_header X-Forwarded-Host $host;—— 防止后端基于错误 Host 生成 URL 或返回 404 -
proxy_set_header Host $host;—— 显式传递原始 Host,避免后端收到127.0.0.1:8000这类上游地址 - (可选)
proxy_set_header X-Forwarded-Port $server_port;—— 当 HTTPS 终止在非标准端口(如 8443)时有用
后端必须主动信任并解析这个头
Nginx 设置了头,后端默认不会读——必须显式启用信任机制:
-
Django:设
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),并开启USE_X_FORWARDED_HOST = True -
Flask:用
ProxyFix中间件,如app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) -
Spring Boot(2.2+):配置
server.forward-headers-strategy=framework,并确保 Tomcat 的RemoteIpValve已启用protocolHeader=x-forwarded-proto -
Express/Node.js:调用
app.set('trust proxy', true),框架会自动读取X-Forwarded-Proto并设置req.protocol
验证是否真正生效
别只看配置文件,动手验证三处:
- 用
curl -I https://your-domain.com和curl -I http://your-domain.com分别请求,检查后端响应中重定向Location头是否协议正确 - 在后端加日志打印
request.headers.get('x-forwarded-proto'),确认值确实是https或http - 打开浏览器开发者工具,访问一个会跳转的页面(如未登录页),看 Network 标签里最终跳转地址、API 返回的绝对 URL、Cookie 的
Secure属性是否符合预期

















