生产环境下3G/WiFi设备中Django/NGINX的CSRF验证失败问题
问题原因分析
1. HTTPS配置不匹配导致Cookie无法传递
你设置了CSRF_COOKIE_SECURE=True和SESSION_COOKIE_SECURE=True,这两个参数要求CSRF和Session Cookie只能通过HTTPS连接传输,但当前NGINX仅监听80端口(HTTP协议),浏览器会拒绝在HTTP请求中携带这些安全Cookie,直接触发CSRF验证失败。
4G设备可能因Cloudflare的自动HTTPS重定向、设备缓存了HTTPS链接,或网络环境默认走HTTPS,所以能正常获取并携带Cookie;而3G/WiFi设备的请求走HTTP协议,无法传递安全Cookie,进而出现验证错误。
2. Cloudflare SSL模式与服务器配置不兼容
如果在Cloudflare后台开启了SSL功能(比如Flexible、Full模式),客户端到Cloudflare是HTTPS连接,但Cloudflare到你的服务器是HTTP连接(因为NGINX未配置HTTPS)。这种情况下:
- Django收到的是HTTP请求,会判定当前连接不安全,不会发送安全Cookie;
- 即便浏览器收到了Cookie,后续请求若走HTTP(比如3G/WiFi下的跳转异常),也不会携带Cookie,导致验证失败。
3. NGINX缺少必要的代理协议头
使用Cloudflare这类反向代理时,Django需要识别真实的请求协议(HTTP/HTTPS),否则会错误判断连接安全性。当前NGINX配置未传递X-Forwarded-Proto头,Django无法感知用户实际使用的是HTTPS,会影响安全Cookie的发送逻辑。
内容的提问来源于stack exchange,提问作者Victor Abuka
相关产品推荐
相关产品推荐

