生产环境Django生成HTTP链接而非HTTPS的问题排查
解决Django部署在EC2(Nginx+Gunicorn)下生成HTTP链接而非HTTPS的问题
核心问题分析
你的Django应用生成的分页等链接始终使用HTTP协议,即便Nginx配置了SSL且请求会重定向到HTTPS,本质原因是Django未正确识别当前请求的实际协议为HTTPS,反向代理传递的协议头没有被正确处理。
具体修复步骤
1. 修正Nginx的代理头传递配置
你的后端Nginx配置中注释了Host相关头,这会导致Django无法正确获取主机名;同时X-Forwarded-Proto用$scheme存在歧义(因为server块同时监听80和443,80端口下$scheme是http)。修改后端location /块:
location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; # 恢复并确保核心代理头正确传递 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 直接硬设为https,避免端口监听带来的协议判断错误 proxy_set_header X-Forwarded-Proto https; }
2. 完善Django的Settings配置
在settings.py中补充以下配置,强化HTTPS识别:
# 确保允许的主机列表包含你的域名 ALLOWED_HOSTS = ['backend.example.com'] # 已有的配置保留,新增以下参数 USE_X_FORWARDED_PORT = True SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
3. 适配Cloudflare的代理头(关键)
由于DNS由Cloudflare管理,请求经过Cloudflare时会发送专属的CF-Visitor头,Django默认配置无法识别这个头。修改SECURE_PROXY_SSL_HEADER为兼容Cloudflare和Nginx的格式:
SECURE_PROXY_SSL_HEADER = ( ('HTTP_X_FORWARDED_PROTO', 'https'), ('HTTP_CF_VISITOR', '{"scheme":"https"}'), )
4. 重启服务使配置生效
修改完成后,依次重启Nginx和Gunicorn:
sudo systemctl restart nginx sudo systemctl restart gunicorn
关于Render平台的特殊说明
Render平台默认会为托管应用自动配置反向代理规则,并正确传递协议头给Django,因此无需手动设置USE_X_FORWARDED_HOST和SECURE_PROXY_SSL_HEADER这类参数。而EC2上是自行搭建的Nginx+Gunicorn环境,必须手动确保所有代理头的传递和识别逻辑正确。
内容的提问来源于stack exchange,提问作者Ayatoo
相关产品推荐
相关产品推荐

