secure_ssl_redirect=true在本地报错,因django开发服务器runserver不支持https,强制跳转会导致“you're accessing the development server over https, but it only supports http”错误;开发环境必须设为false,生产环境需配合反向代理透传x-forwarded-proto头并正确配置secure_proxy_ssl_header。

SECURE_SSL_REDIRECT=True 为什么在本地直接报错
因为 runserver 不支持 HTTPS,而 SECURE_SSL_REDIRECT=True 会强制对所有 HTTP 请求返回 301 跳转到 HTTPS 地址。浏览器一旦用 https://localhost:8000 访问,Django 就会尝试重定向,但开发服务器根本无法响应 HTTPS 请求,直接抛出 You're accessing the development server over HTTPS, but it only supports HTTP. 错误。
所以开发环境必须设为:SECURE_SSL_REDIRECT=False;生产环境才可设为 True,且前提是反向代理(如 Nginx)已终止 HTTPS 并透传协议头。
- 不要在
settings.py里硬编码SECURE_SSL_REDIRECT=True,应按环境区分 - 即使改回
False,浏览器可能仍缓存了之前的 301 跳转,需用隐身窗口或清空缓存验证 - 若使用 Docker 或云服务(如 Cloudflare),要确认它们是否默认透传
X-Forwarded-Proto,否则 Django 始终认为是 HTTP
SECURE_PROXY_SSL_HEADER 必须配对设置,且值要严格匹配
SECURE_PROXY_SSL_HEADER 是元组,不是字符串,格式必须是 ('HTTP_X_FORWARDED_PROTO', 'https')。Django 默认不信任任何外部头,只有明确声明的头名 + 值组合才被接受为“可信的 HTTPS 来源”。
Nginx 配置中必须同步设置:proxy_set_header X-Forwarded-Proto $scheme;。如果 Nginx 实际传的是 X-Forwarded-Protocol: https,而 Django 期待的是 X-Forwarded-Proto,跳转逻辑就完全失效。
- Apache 用户注意:头名可能是
HTTP_X_FORWARDED_SCHEME或HTTP_X_FORWARDED_SSL,需根据mod_headers实际输出调整 - 值必须全小写
'https',写成'HTTPS'或'HttpS'都不匹配 - 该配置仅在
SECURE_SSL_REDIRECT=True时生效,单独设置无意义
其他关键安全响应头要手动启用
Django 不自动注入 Strict-Transport-Security、Content-Security-Policy 等头,需靠中间件或响应钩子补充。最简单方式是在 MIDDLEWARE 中加入 django.middleware.security.SecurityMiddleware,并配置对应选项:
-
SECURE_HSTS_SECONDS = 31536000(推荐一年,首次上线可先设 300 测试) -
SECURE_HSTS_INCLUDE_SUBDOMAINS = True(若你有子域名,否则可能阻断访问) -
SECURE_CONTENT_TYPE_NOSNIFF = True(防 MIME 类型嗅探) -
SECURE_BROWSER_XSS_FILTER = True(已弃用,Django 4.0+ 移除,仅旧项目需留意)
注意:SecurityMiddleware 必须放在 MIDDLEWARE 列表靠前位置(通常在 CommonMiddleware 之前),否则头可能被后续中间件覆盖。
证书文件本身不归 Django 管理,Nginx/Apache 才是 HTTPS 终结点
Django 应用本身不处理 SSL/TLS 握手。证书(.crt 或 .pem)和私钥(.key)必须由反向代理加载。例如 Nginx 配置中:
ssl_certificate /usr/share/nginx/ssl/your_domain.crt; ssl_certificate_key /usr/share/nginx/ssl/your_domain.key;
路径必须可被 Nginx 进程读取(常因权限问题导致 502)。Django 只需通过 X-Forwarded-Proto 知道“外面已经是 HTTPS”,然后决定是否跳转、是否加 HSTS 头。
容易忽略的一点:云服务商(如 AWS ALB、Cloudflare)可能把证书托管在控制台,此时 Nginx 不需要配置证书,但仍需确保它把 X-Forwarded-Proto 正确传递给后端——否则 Django 完全不知道请求来源是 HTTPS。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











