You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Vite传CSRF令牌仍触发Django 403错误(CSRF Cookie未设置)

解决React + Django CSRF 403错误(CSRF Cookie未设置)

以下是针对问题的具体修复方案,按优先级排序:

1. 修正Django中间件顺序

你的MIDDLEWARE中SessionMiddleware在CsrfViewMiddleware之后,这会导致CSRF验证无法正确关联会话,是引发403错误的核心原因。必须将SessionMiddleware移到CsrfViewMiddleware之前:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  # 调整到此处
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # ... 其他中间件 ...
]

2. 简化前端CSRF获取逻辑

你当前手动从接口返回值提取CSRF token并存入cookie,但@ensure_csrf_cookie装饰器已经会在响应中自动设置csrftoken cookie,无需手动覆盖。修改前端代码如下:

// 仅触发接口让Django设置cookie,无需处理返回值
useEffect(() => {
    getCSRFToken();
}, []);

const getCSRFToken = async () => {
    const apiUrl = import.meta.env.VITE_API_URL;
    await fetch(`${apiUrl}getCSRFToken/`, {
        method: "GET",
        credentials: "include",
    });
};

提交表单时保留原有的Cookies.get("csrftoken")逻辑即可。

3. 验证CSRF_TRUSTED_ORIGINS的完整性

确保CSRF_TRUSTED_ORIGINS包含完整的协议、域名和端口,比如前端为https://your-frontend.com:3000,则配置:

CSRF_TRUSTED_ORIGINS = [
    env('FRONTEND_URL'),  # 确保环境变量是完整URL,如"https://your-frontend.com:3000"
]

本地开发时需写http://localhost:5173而非仅localhost。

4. 检查FormData提交的特殊配置

使用FormData作为请求体时,fetch会自动设置Content-Type为multipart/form-data,此时需注意:

  • 不要手动设置Content-Type头,否则会破坏FormData的边界标识
  • 在浏览器开发者工具的网络标签中,确认请求头的X-CSRFToken与cookie中的csrftoken值完全一致

5. 确认CSRF Cookie属性配置

根据部署场景调整以下配置:

CSRF_COOKIE_SAMESITE = 'None'  # 跨域场景必须设为None
CSRF_COOKIE_SECURE = True      # 仅当前后端都用HTTPS时设为True,本地HTTP开发设为False
CSRF_COOKIE_HTTPONLY = False   # 允许前端读取cookie,配置正确

本地HTTP开发时CSRF_COOKIE_SECURE必须设为False,否则浏览器不会保存cookie。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:25:58