You need to enable JavaScript to run this app. Django与React解耦开发:CSRF令牌不匹配、Cookie持久化异常
优惠活动
大模型
产品
解决方案
定价
更多

Django与React解耦开发:CSRF令牌不匹配、Cookie持久化异常

问题根因定位

响应取值不匹配的本质

这是Django 4.0+版本调整CSRF机制后的正常表现,不属于代码bug:

  • Set-Cookie头中的csrftoken值,存储的是服务端生成的高熵原始CSRF密钥,对应示例里的KceWlQsdiQuM.......段
  • 自定义响应头X-CSRFToken返回给前端的,是基于这份原始密钥动态计算生成的掩码验证令牌,对应示例里的Ymx3NCe5dwh.......段
  • 两个值从设计逻辑上就不是完全相同的字符串,服务端校验时会将前端提交的掩码令牌解算,与Cookie中存储的原始密钥做一致性校验,算法匹配即可通过。老版本Django中Cookie存储内容和返回前端的令牌值完全一致,版本迭代后拆分了存储和验证逻辑,才会出现内容差异。

旧Cookie无法覆盖的原因

Django的CSRF Cookie更新有明确的触发条件,当前代码缺失关键触发逻辑:

  • 定义的CSRF获取视图没有添加@ensure_csrf_cookie装饰器,CsrfViewMiddleware默认不会在每次请求时主动刷新CSRF Cookie,只有被该装饰器标记的视图,才会触发Cookie的写入、更新流程
  • 缺失触发逻辑时,中间件检测到请求已经携带有效CSRF Cookie,就不会在响应中下发新的Cookie值,导致旧值持续留存
  • 配置项CSRF_COOKIE_AGE = None会让CSRF Cookie变成会话级临时Cookie,只要浏览器会话不关闭,旧值会一直存在,进一步放大不更新的异常表现
  • 配置项CSRF_COOKIE_SAMESITE = 'Strict'在跨端口本地调试场景下,会导致浏览器跨源请求时直接不携带已有Cookie,也会干扰Cookie的正常更新流程
修复方案
  • 修改Django端CSRF视图代码,补全必要的装饰器逻辑:
from django.middleware.csrf import get_token, ensure_csrf_cookie
from django.http import JsonResponse
@ensure_csrf_cookie
def get_csrf_token(request):
    csrf_token = get_token(request)
    response = JsonResponse({'detail': 'CSRF cookie set'})
    response['X-CSRFToken'] = csrf_token
    return response
  • 调整CSRF相关配置适配前后端分离场景:
    • 将CSRF_COOKIE_AGE = None改为合理的长过期值(如Django默认的31449600秒),解决会话级Cookie临时留存的问题
    • 本地跨端口调试时,将CSRF_COOKIE_SAMESITE临时改为'Lax',生产环境同域部署后再切回'Strict'
    • 保留CSRF_COOKIE_HTTPONLY = True的配置,该配置可避免注入脚本读取CSRF Cookie,配合从X-CSRFToken响应头读取令牌的逻辑,是匹配当前前端方案的安全配置
  • 前端现有fetch逻辑无需修改,确保所有需要CSRF校验的POST/PUT/DELETE请求,将之前获取的csrf状态值设置到X-CSRFToken请求头即可,不需要手动从Cookie中读取令牌
验证流程
  • 清理浏览器中已有的旧csrftokenCookie,重新调用/api/csrf/接口
  • 确认响应中会正常下发与原始密钥对应的Set-Cookie头,后续所有同域请求都会自动携带该Cookie
  • 向后端提交携带CSRF头的请求,确认可以通过服务端的CSRF校验,无需纠结Cookie存储值和返回的令牌值是否完全一致

内容的提问来源于stack exchange,提问作者rpdjprog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.09 13:15:05