Django CSRF 验证失败的根源与双重提交 Cookie 正确实现方案

发布时间 - 2026-01-04 00:00:00    点击率:

django 前后端分离场景下 csrf 验证失败,常因未同时传递 cookie 和 `x-csrftoken` 请求头所致;本文详解“双重提交 cookie”机制原理、配置要点及 nginx 代理下的关键修复步骤。

在 Django 前后端分离架构中(如前端运行于 http://dev.admin.lt,后端 API 部署于 https://api.admin.lt),CSRF 验证持续失败的根本原因往往并非配置遗漏,而是对 Django CSRF 防护机制的理解偏差——Django 默认采用 Double Submit Cookie(双重提交 Cookie) 模式,它要求客户端必须同时满足两个条件

  1. ✅ 在请求 Cookie 中携带 csrftoken(由 Django 自动设置,HttpOnly 安全属性不影响读取);
  2. ✅ 在请求头中显式传递 X-CSRFToken 字段,其值必须与 Cookie 中的 csrftoken 完全一致

仅传 Cookie 或仅传 Header 均会触发 403 Forbidden: CSRF verification failed 错误——这正是你观察到 request.headers 中缺失 X-CSRFToken 的原因:Django 不会自动从 Cookie 提取并注入该 Header,必须由前端主动设置。

✅ 正确的前端请求示例(JavaScript / Axios)

// 1. 先获取 csrftoken(通常从登录响应或独立 endpoint 获取)
const getCookie = (name) => {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);  
  return parts.length === 2 ? parts.pop().split(';').shift() : null;
};

// 2. 发起 POST 请求时,同时设置 Cookie(浏览器自动携带)和 X-CSRFToken Header
axios.post('https://api.admin.lt/auth/login/', { username, password }, {
  headers: {
    'X-CSRFToken': getCookie('csrftoken'), // ⚠️ 必须显式设置!
    'Content-Type': 'application/json',
  },
  withCredentials: true // ⚠️ 关键:启用凭据(含 Cookie)跨域发送
});

? 关键配置核查清单(Django + Nginx)

项目 正确配置 说明
CSRF_COOKIE_SECURE True 因使用 HTTPS,必须开启,否则 Cookie 不会被浏览器发送
CSRF_COOKIE_HTTPONLY False(⚠️ 重点修正) True 会阻止 JavaScript 读取 Cookie → 无法获取 token 填入 X-CSRFToken header!前后端分离场景下必须设为 False
CSRF_COOKIE_SAMESITE 'Lax'(推荐)或 'None'(若需跨站) 若设为 None,必须同时启用 CSRF_COOKIE_SECURE=True;'Lax' 在多数场景更安全且兼容性好
CSRF_COOKIE_DOMAIN '.admin.lt'(带前导点) 确保 Cookie 能被 dev.admin.lt、api.admin.lt 等子域共享
Nginx proxy_set_header 必须添加
proxy_set_header X-CSRFToken $http_x_csrf_token;
否则 Nginx 会剥离自定义 Header!你的当前配置缺失此行,导致 X-CSRFToken 根本未到达 Django
? Nginx 修复配置(追加至 location / 块内):location / { proxy_pass http://localhost:8000; proxy_set_header X-CSRFToken $http_x_csrf_token; # ← 关键!透传 CSRF Header proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; # ... 其他已有配置保持不变 }

⚠️ 其他易错点排查

  • CORS_ALLOW_CREDENTIALS = True:已正确配置,确保前端 withCredentials: true 生效;
  • CSRF_TRUSTED_ORIGINS:必须包含前端完整协议+域名(如 "http://dev.admin.lt" 和 "https://dev.admin.lt" 需同时列出);
  • ALLOWED_HOSTS:应包含 api.admin.lt 和可能的负载均衡 IP(如 ['api.admin.lt', '127.0.0.1']);
  • 中间件顺序:确保 'django.middleware.csrf.CsrfViewMiddleware' 在 'django.contrib.sessions.middleware.SessionMiddleware' 之后、且未被 CORS 中间件错误拦截。

✅ 验证是否生效

  1. 使用浏览器开发者工具 → Network → 查看请求的 Request Headers:确认同时存在 Cookie: csrftoken=xxx 和 X-CSRFToken: xxx;
  2. 在 Django 视图中临时打印:
    def login_view(request):
        print("CSRF Token in header:", request.META.get('HTTP_X_CSRFTOKEN'))
        print("CSRF Token in cookie:", request.COOKIES.get('csrftoken'))
        # ... 业务逻辑

    二者值应完全一致。

总结:Django CSRF 的“双重提交”不是可选优化,而是强制安全模型。解决核心在于——前端严格同步传递 Cookie 与 Header,Django 后端开放可读 Cookie(HttpOnly=False),Nginx 准确透传自定义 Header。三者缺一不可。


# javascript  # word  # java  # js  # 前端  # json  # go  # nginx  # cookie  # 浏览器  # app 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  Linux网络带宽限制_tc配置实践解析【教程】  北京专业网站制作设计师招聘,北京白云观官方网站?  大型企业网站制作流程,做网站需要注册公司吗?  jQuery中的100个技巧汇总  Laravel如何发送系统通知?(Notification渠道示例)  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  详解jQuery中基本的动画方法  网站建设整体流程解析,建站其实很容易!  Laravel如何实现数据库事务?(DB Facade示例)  如何在新浪SAE免费搭建个人博客?  如何在云主机上快速搭建网站?  JavaScript实现Fly Bird小游戏  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  JS弹性运动实现方法分析  Laravel如何集成Inertia.js与Vue/React?(安装配置)  如何快速查询域名建站关键信息?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Laravel如何使用Collections进行数据处理?(实用方法示例)  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  专业商城网站制作公司有哪些,pi商城官网是哪个?  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  如何在服务器上三步完成建站并提升流量?  网站制作报价单模板图片,小松挖机官方网站报价?  HTML 中动态设置元素 name 属性的正确语法详解  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  高端建站三要素:定制模板、企业官网与响应式设计优化  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Linux系统命令中screen命令详解  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  如何在腾讯云服务器快速搭建个人网站?  Laravel如何使用Blade模板引擎?(完整语法和示例)  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  php 三元运算符实例详细介绍  详解Huffman编码算法之Java实现  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  实例解析Array和String方法  php打包exe后无法访问网络共享_共享权限设置方法【教程】  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  LinuxShell函数封装方法_脚本复用设计思路【教程】  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  三星、SK海力士获美批准:可向中国出口芯片制造设备  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  Laravel模型事件有哪些_Laravel Model Event生命周期详解  Laravel用户密码怎么加密_Laravel Hash门面使用教程  JavaScript模板引擎Template.js使用详解