You need to enable JavaScript to run this app. Django项目设置CSRF_COOKIE_HTTPONLY=True时触发403 CSRF错误的原因排查
优惠活动
大模型
产品
解决方案
定价
更多

Django项目设置CSRF_COOKIE_HTTPONLY=True时触发403 CSRF错误的原因排查

问题根因

设置CSRF_COOKIE_HTTPONLY = True后,Django下发的csrftokenCookie会被附加HttpOnly响应标记,浏览器会强制限制所有前端JavaScript代码(包括Axios内置的CSRF处理逻辑)无法通过document.cookie读取该Cookie的具体内容。

你当前前端的CSRF处理完全依赖Axios内置逻辑:发送请求前,先读取配置的xsrfCookieName(即csrftoken)对应的Cookie值,再将这个值写入xsrfHeaderName指定的X-CSRFToken请求头,随请求发送给后端。
当csrftoken被HttpOnly保护时,Axios根本读不到Cookie里存储的CSRF值,最终发出的X-CSRFToken请求头为空。你自定义的enforce_csrf校验逻辑自然会判定CSRF值缺失,抛出“CSRF token missing or incorrect”的403错误。

常见认知误区:开启CORS_ALLOW_CREDENTIALS = True后,浏览器确实会自动把所有Cookie(包括HttpOnly属性的)随请求带给后端,但后端CSRF校验要求前端把CSRF值从Cookie中读出、放到请求头里做二次匹配,这个过程是纯JS层的操作,和Cookie自动携带的机制完全独立,HttpOnly标记会直接阻断这个读取操作。

当你把CSRF_COOKIE_HTTPONLY = False时,前端JS可以正常读取csrftoken的Cookie值,Axios能把值正确填充到请求头中,后端CSRF校验自然就能通过。

可选解决方案
  • 通用适配跨域前后端分离场景的最优方案:单独关闭CSRF Cookie的HttpOnly标记,保留SESSION Cookie的HttpOnly配置。也就是将CSRF_COOKIE_HTTPONLY调整回False,同时维持SESSION_COOKIE_HTTPONLY = True的安全配置。这种配置既不影响前端正常读取CSRF值、完成校验流程,也不会丢失SESSION Cookie的XSS防护能力,是Django官方针对跨域场景的推荐配置。
  • 如果必须保持CSRF_COOKIE_HTTPONLY = True:
    • 若你的JWT凭证是存储在前端localStorage而非Cookie中,CSRF攻击根本无法伪造带身份的跨域请求(跨域请求不会自动携带localStorage中的内容),可以直接删除自定义认证中对enforce_csrf的调用,从根源上跳过CSRF校验流程。
    • 若你的JWT也是存储在HttpOnly Cookie中,需要重写整套CSRF校验逻辑,让CSRF值和JWT凭证绑定在同一个HttpOnly Cookie内,完全不依赖前端JS读取传递CSRF值。这种方案改动量较大,通用业务场景下性价比很低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 15:36:01