Django REST + React 跨域CORS下CSRF认证403错误排查问询
核心问题原因
你的前端运行在http://localhost:3000,后端运行在http://localhost:8000,二者属于不同源:
- 前端模块初始化时直接执行
getCookie('csrftoken'),此时还未向后端发起过任何请求,后端没有给前端种下csrftokenCookie,拿到的值必然为空 - 直接给
/calc/接口加ensure_csrf_cookie装饰器无效,因为你首次请求该接口用的是POST方法,OPTIONS预检请求不会返回CSRF Cookie,POST请求发送时还不存在有效Cookie
修复步骤
Django后端修改
- 补充
settings.py配置
# 开发环境配置 CSRF_COOKIE_HTTPONLY = False # 允许前端JS读取CSRF Cookie,默认值为False,如果你手动修改过请改回 CSRF_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SAMESITE = 'Lax' # 生产环境HTTPS下请替换为以下配置 # CSRF_COOKIE_SECURE = True # SESSION_COOKIE_SECURE = True # CSRF_COOKIE_SAMESITE = 'None' # SESSION_COOKIE_SAMESITE = 'None'
- 新增CSRF Cookie获取接口
在urls.py中新增以下代码:
from django.http import JsonResponse from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def get_csrf_token(request): return JsonResponse({"status": "success"}) urlpatterns = [ # 原有路由保持不变 path("api/get-csrf/", get_csrf_token, name="get_csrf"), ]
React前端修改
- 删掉
CsrfToken.js中模块初始化阶段的const csrftoken = getCookie('csrftoken')语句,把getCookie方法单独导出 - 应用初始化时先调用CSRF获取接口,种下有效CSRF Cookie,修改
App.js:
import { useEffect } from 'react' import { getCookie } from './CsrfToken' function App() { // 应用加载时先获取CSRF Cookie useEffect(() => { fetch("http://localhost:8000/api/get-csrf/", { method: "GET", credentials: 'include', mode: 'cors' }) }, []) const getdata = () => { setFetching(true); const bod = { // 请求参数 }; // 每次发请求前动态获取CSRF Token const csrftoken = getCookie('csrftoken'); fetch("http://localhost:8000/calc/", { method: "POST", credentials: 'include', mode: 'cors', headers: { 'Accept': 'application/json', "Content-Type": "application/json", 'X-CSRFToken': csrftoken, }, body: JSON.stringify(bod), }) // 原有请求后续逻辑保持不变 } // 其他代码保持不变 }
内容的提问来源于stack exchange,提问作者Romn
相关产品推荐
相关产品推荐

