
本文详解 React 前端与 Django 后端跨域通信时 CSRF Cookie 不生效的根本原因及全套配置方案,涵盖 SameSite、Secure、CORS、会话与 CSRF 中间件协同配置,并提供可验证的代码实践。
本文详解 react 前端与 django 后端跨域通信时 csrf cookie 不生效的根本原因及全套配置方案,涵盖 `samesite`、`secure`、cors、会话与 csrf 中间件协同配置,并提供可验证的代码实践。
在 React(运行于沙箱域名如 https://7w37f9-3000.csb.app)与 Django 后端(部署于 https://eliptum.tech)进行跨域请求时,即使已启用 withCredentials: true、正确配置 django-cors-headers 并手动调用 response.set_cookie(..., samesite='None', secure=True),仍频繁报错 CSRF cookie not set——这表明浏览器根本未接收或存储 csrftoken Cookie。问题核心并非 CORS 或前端逻辑,而在于 Django 内置 CSRF 中间件对 Cookie 的默认行为与跨域场景不兼容。
✅ 关键缺失:CSRF_COOKIE_SAMESITE = 'None'
Django 的 CsrfViewMiddleware 在生成和校验 CSRF Token 时,独立于视图层的 set_cookie() 调用,它会自动写入名为 csrftoken 的 Cookie,但其 SameSite 属性由 CSRF_COOKIE_SAMESITE 设置控制。若该配置未显式设为 'None',Django 默认使用 'Lax'(Django ≥ 3.1),而 'Lax' 在跨站 POST 请求中不会发送 Cookie,导致后端校验失败。
因此,必须在 settings.py 中补充以下关键配置:
# settings.py —— 必须添加 CSRF_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SECURE = True # 强制仅通过 HTTPS 传输(生产环境必需) CSRF_COOKIE_HTTPONLY = False # 允许 JavaScript 读取(因需提取 token 用于 X-CSRFToken 头)
⚠️ 注意:CSRF_COOKIE_SECURE = True 与 CSRF_COOKIE_SAMESITE = 'None' 必须同时启用。浏览器规范要求:当 SameSite=None 时,Secure 必须为 True,否则 Cookie 将被拒绝。
? 全链路配置核查清单
除上述核心项外,以下配置缺一不可,需全部确认:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| CORS_ALLOW_CREDENTIALS | True | 允许浏览器发送凭据(Cookie、认证头) |
| CORS_ALLOWED_ORIGINS | ['https://eliptum.tech', 'https://7w37f9-3000.csb.app'] | 显式声明可信源(CORS_ORIGIN_WHITELIST 已弃用) |
| CSRF_TRUSTED_ORIGINS | 同上 | 至关重要:Django 5.0+ 要求跨域提交 CSRF 表单/请求的源必须在此列表中 |
| SESSION_COOKIE_SAMESITE | 'None' | 若依赖 Session ID(如你的 RSA 密钥绑定 session),也需同步设置 |
| SESSION_COOKIE_SECURE | True | 与 CSRF_COOKIE_SECURE 保持一致 |
更新后的关键配置片段示例:
# settings.py
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
"https://eliptum.tech",
"https://7w37f9-3000.csb.app",
]
CSRF_TRUSTED_ORIGINS = CORS_ALLOWED_ORIGINS # 必须!否则 CSRF 校验直接拒绝请求
CSRF_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = False
SESSION_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SECURE = True
? 前端 Axios 请求优化建议
确保请求链路无遗漏:
强戈环形山: q15040409-刻画家功能概述强戈环形山: q15040409-刻画家是一项面向实际任务的技能,主要用于平顶山: 维西翁: 1:1.0. 塔格斯: rap.github: 自动化。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该
// 获取公钥与 CSRF Token(自动携带并接收 Cookie)
const public_key_r = await axios.get("https://eliptum.tech/get-public-key", {
withCredentials: true,
});
// 提交注册(携带 Cookie + 手动设置 X-CSRFToken 头)
const response = await axios.post(
"https://eliptum.tech/user/create",
{ username, encryptedPassword, email, phone_number: phoneNumber },
{
withCredentials: true,
headers: {
"X-CSRFToken": public_key_r.data.csrf_token, // 从响应体中提取
},
}
);
? 提示:无需在视图中手动 response.set_cookie('csrftoken', ...)。Django 的 get_token(request) 已触发中间件写入逻辑,只需确保 CSRF_COOKIE_* 配置正确,中间件会自动注入安全 Cookie。
? 验证与调试技巧
-
检查响应头:在浏览器 DevTools → Network → 查看 /get-public-key 响应头,确认存在:
Set-Cookie: csrftoken=abc123...; expires=...; HttpOnly; Max-Age=31449600; Path=/; SameSite=None; Secure Access-Control-Allow-Credentials: true
-
检查请求头:发起 /user/create 请求时,确认请求头包含:
Cookie: csrftoken=abc123...; sessionid=xyz789... X-CSRFToken: abc123...
禁用浏览器缓存测试:有时旧 Cookie 缓存干扰,可开启隐身窗口或清空站点数据重试。
✅ 总结
跨域场景下 Django CSRF Cookie 失效的根因,90% 源于 CSRF_COOKIE_SAMESITE 未显式设为 'None'。它与 CSRF_COOKIE_SECURE、CORS_ALLOW_CREDENTIALS、CSRF_TRUSTED_ORIGINS 构成四要素闭环。任何一项缺失都将导致 Cookie 无法传递或校验失败。完成配置后,无需修改视图逻辑,Django 中间件将自动、安全地处理跨域 CSRF 流程。务必在 HTTPS 环境下测试——HTTP + SameSite=None 将被所有现代浏览器静默丢弃。










