Django与React跨域CSRF认证失败(HTTP 403)求解决
Django+React跨域CSRF 403认证失败解决方案
问题排查与修复步骤
1. 修正中间件顺序(核心问题)
Django的CorsMiddleware必须放在CommonMiddleware之前,否则无法正确处理跨域请求的Cookie传递,同时要避免重复添加CommonMiddleware。
修改settings.py中的MIDDLEWARE配置:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'corsheaders.middleware.CorsMiddleware', # 移至此处,确保在CommonMiddleware之前 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
2. 统一前后端域名,避免Cookie域不匹配
浏览器会将localhost和127.0.0.1视为不同域名,导致Cookie无法共享,需统一请求地址:
- 修改
App.jsx中的请求地址:
// 原代码 axios.get('http://127.0.0.1:8000/api/csrf/', { withCredentials: true }) // 修改为 axios.get('http://localhost:8000/api/csrf/', { withCredentials: true })
- 修改
AddFavorite.jsx中的请求地址:
// 原代码 await axios.post('http://127.0.0.1:8000/api/favourites/add/', { ... }) // 修改为 await axios.post('http://localhost:8000/api/favourites/add/', { ... })
3. 简化CSRF Token处理,让Axios自动管理
无需手动存储和设置Token,Axios可自动从Cookie读取并注入请求头:
修改App.jsx中的useEffect逻辑:
useEffect(() => { // 配置Axios自动处理CSRF axios.defaults.withCredentials = true; axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'X-CSRFToken'; // 仅触发CSRF Cookie初始化,无需手动存储Token axios.get('http://localhost:8000/api/csrf/') .then(() => console.log('CSRF Cookie已初始化')) .catch(error => console.error('初始化CSRF失败:', error)); }, []);
删除AddFavorite.jsx中请求时手动设置的headers(Axios会自动处理):
// 原代码 await axios.post('http://localhost:8000/api/favourites/add/', { name, latitude, longitude, }, { headers: { 'X-CSRFToken': cookies.csrftoken } }) // 修改为 await axios.post('http://localhost:8000/api/favourites/add/', { name, latitude, longitude, })
4. 完善CSRF Cookie配置(可选,增强跨域兼容性)
在settings.py中添加以下配置:
# 允许跨域场景下Cookie正常传递 CSRF_COOKIE_SAMESITE = 'Lax' # 本地开发用Lax即可,生产HTTPS环境可设为None CSRF_COOKIE_SECURE = False # 本地HTTP环境设为False,HTTPS环境设为True
验证步骤
- 重启Django后端和React前端
- 打开浏览器开发者工具(F12),在Application标签下查看
localhost:8000的Cookie中是否存在csrftoken - 发起POST请求时,在Network标签中确认请求头包含
X-CSRFToken,且值与Cookie中的csrftoken一致
内容的提问来源于stack exchange,提问作者Oliver-René Goltsche
相关产品推荐
相关产品推荐

