
本文详解如何在 React 前端(跨域)与 Django 后端通信时,正确配置 CSRF Cookie 的跨域传输,重点解决 CSRF cookie not set 错误,涵盖 SameSite=None、Secure、CORS 及 Axios 协同配置。
本文详解如何在 react 前端(跨域)与 django 后端通信时,正确配置 csrf cookie 的跨域传输,重点解决 `csrf cookie not set` 错误,涵盖 `samesite=none`、`secure`、cors 及 axios 协同配置。
在现代前后端分离架构中,React 应用部署在独立域名(如 CodeSandbox 的 https://7w37f9-3000.csb.app),而 Django 后端运行在 https://eliptum.tech,二者构成典型的跨域场景。此时若需启用 Django 的 CSRF 保护机制(尤其对 POST/PUT/DELETE 等敏感请求),必须确保 CSRF Token 既能由后端安全下发为 Cookie,又能被前端在后续请求中自动携带——但实践中常因配置疏漏导致浏览器拒绝写入或发送 Cookie,最终抛出 CSRF cookie not set. 错误。
根本原因在于:Django 默认的 CSRF Cookie 配置(CSRF_COOKIE_SAMESITE = 'Lax')禁止其在跨站请求中被浏览器自动包含,即使你已在响应头中手动调用 response.set_cookie(..., samesite='None', secure=True),Django 内部中间件(如 CsrfViewMiddleware)仍会依据全局设置覆盖或忽略该 Cookie 的跨域行为。
✅ 正确解法是全局显式声明 CSRF Cookie 的跨域策略,而非仅依赖视图层手动设置:
# settings.py CSRF_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SECURE = True # 必须为 True,否则 'SameSite=None' 会被浏览器拒绝 CSRF_COOKIE_HTTPONLY = False # 允许 JavaScript 读取(如需通过 document.cookie 获取) CSRF_COOKIE_PATH = '/' # 确保路径覆盖所有 API 端点
⚠️ 注意:CSRF_COOKIE_SECURE = True 是强制前提。SameSite=None 仅在 Secure(即 HTTPS)上下文中被现代浏览器接受;若开发环境使用 HTTP(如 localhost:3000),请改用 CSRF_COOKIE_SECURE = False 并搭配 CSRF_COOKIE_SAMESITE = 'Lax'(仅限开发),但生产环境务必启用 HTTPS。
同时,确保其他关键配置已就位(你已基本完成,此处强调完整性):
强戈环形山: q15040409-刻画家功能概述强戈环形山: q15040409-刻画家是一项面向实际任务的技能,主要用于平顶山: 维西翁: 1:1.0. 塔格斯: rap.github: 自动化。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该
- ✅ CORS_ALLOW_CREDENTIALS = True
- ✅ CORS_ALLOWED_ORIGINS = ['https://eliptum.tech', 'https://7w37f9-3000.csb.app'](注意:CORS_ORIGIN_WHITELIST 已被弃用,以 CORS_ALLOWED_ORIGINS 为准)
- ✅ CSRF_TRUSTED_ORIGINS = ['https://eliptum.tech', 'https://7w37f9-3000.csb.app'](Django 4.0+ 必需,用于验证 Referer 头)
- ✅ 前端 Axios 请求始终携带 withCredentials: true(你已正确设置)
- ✅ 后端视图响应中无需重复 set_cookie('csrftoken', ...) —— Django 会在 CsrfViewMiddleware 中自动注入符合上述全局配置的 Cookie(包括 Set-Cookie: csrftoken=...; Path=/; SameSite=None; Secure; HttpOnly)
示例修正后的视图(精简版,移除冗余手动 set_cookie):
from django.views import View
from django.http import JsonResponse
from django.middleware.csrf import get_token
class PublicKeyView(View):
def get(self, request):
# ... 密钥生成逻辑保持不变 ...
public_key = public_key.decode('utf-8') if isinstance(public_key, bytes) else public_key
csrf_token = get_token(request)
response_data = {
"public_key": public_key,
"csrf_token": csrf_token # 供前端调试查看,非必需
}
return JsonResponse(response_data)
# ✅ Django 自动添加符合 settings.py 的 csrftoken Cookie
最后,验证请求链路是否生效:
- 浏览器开发者工具 → Application → Cookies → 检查 https://eliptum.tech 下是否存在 csrftoken Cookie,且 SameSite 显示为 None,Secure 为 True;
- Network 面板中,get-public-key 响应头应包含:
Set-Cookie: csrftoken=xxx; Path=/; SameSite=None; Secure; HttpOnly
Access-Control-Allow-Origin: https://7w37f9-3000.csb.app
Access-Control-Allow-Credentials: true - 后续 POST /user/create 请求的请求头中,浏览器应自动携带 Cookie: csrftoken=xxx(无需 Axios 手动添加)。
? 小结:
- 核心缺失项:CSRF_COOKIE_SAMESITE = 'None' + CSRF_COOKIE_SECURE = True 是跨域 CSRF Cookie 生效的黄金组合;
- 避免重复操作:不要在视图中手动 set_cookie('csrftoken'),以免与 Django 中间件冲突;
- 全链路 HTTPS:生产环境必须确保前后端均通过 HTTPS 访问,否则 SameSite=None 将失效;
- 浏览器兼容性:Firefox 69+、Chrome 80+、Safari 12+ 均支持该配置,旧版需降级方案(如 Token 透传 Header)。
完成上述配置后,CSRF cookie not set 错误将彻底消失,跨域 CSRF 保护即可稳定工作。










