必须配置proxy_set_header X-Forwarded-Proto $scheme并置于proxy_pass前,同时后端需显式信任该头,否则因协议信息丢失导致http链接生成、重定向循环及Secure Cookie失效。

HTTPS 卸载后,后端看到的全是 HTTP 请求,但用户实际访问的是 HTTPS。如果不告诉后端真实协议,就会生成 http:// 链接、跳转回 HTTP、Secure Cookie 被浏览器拒绝——根本原因是协议信息丢失。解决的关键就是用 proxy_set_header 把原始协议透传过去,并让后端真正信任它。
必须设置 X-Forwarded-Proto $scheme
这一行不能省略,也不能写错:
- 放在
location块里,且必须在proxy_pass指令之前 - 写成
proxy_set_header X-Forwarded-Proto $scheme;——$scheme是 Nginx 内置变量,自动取值http或https,取决于客户端连的是 80 还是 443 端口 - 绝不能硬编码为
https,否则 HTTP 访问也会被标记成 HTTPS,引发重定向循环或 CSRF 校验失败 - 如果 Nginx 前还有 CDN(如 Cloudflare),且 CDN 已设该头,应改用
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;,避免覆盖真实值
配套转发头要一起配齐
只传协议不够,后端构建 URL、判断 Host、记录 IP 都需要完整上下文:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
-
proxy_set_header Host $http_host;—— 保留原始 Host 和端口(比如example.com:443),比$host更准确 -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 支持多层代理,安全追加客户端真实 IP -
proxy_set_header X-Real-IP $remote_addr;—— 直接传递发起请求的客户端 IP,用于日志和风控 -
proxy_set_header X-Forwarded-Host $host;和X-Forwarded-Port $server_port;—— 帮助后端拼出正确的跳转地址和绝对链接
后端必须显式信任这个头
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', '127.0.0.1'),框架才会把req.protocol设为https
验证是否真正生效
别只检查配置文件有没有写,要从请求链路末端确认:
- 在后端加日志打印
req.headers['x-forwarded-proto'](Node)或request.META.get('HTTP_X_FORWARDED_PROTO')(Django)——HTTPS 访问时必须输出https - 用
curl -I https://your-domain.com查看重定向响应头,Location必须是https://开头 - 打开浏览器开发者工具 → Network → 查任意一个 API 请求,确认请求头含
X-Forwarded-Proto: https,且返回内容里的链接全为 HTTPS

















