React前端搭配Django后端时,如何正确处理CSRF验证?
Django + 纯React前后端分离场景下的CSRF验证方案(含登录场景)
针对前后端分离的登录场景,完全不需要假设用户已登录,下面是完整的落地步骤:
后端处理
给登录接口添加@ensure_csrf_cookie装饰器——这个装饰器的核心作用是无论用户是否已认证,只要访问该接口,Django就会在响应中设置CSRF Cookie,不需要依赖任何前置登录状态。
示例代码:
from django.views.decorators.csrf import ensure_csrf_cookie from django.http import JsonResponse @ensure_csrf_cookie def login_view(request): if request.method == 'GET': # 仅用于触发Django设置CSRF Cookie,无需返回业务内容 return JsonResponse({'status': 'ready'}) elif request.method == 'PUT': # 处理登录逻辑:验证用户名密码、生成认证Token等 return JsonResponse({'auth_token': 'your_generated_token'})
前端处理流程
渲染登录页后先拉取CSRF Cookie:
React加载登录页面后,先发起一个GET请求到登录接口,目的是让Django把CSRF Cookie写入浏览器。提取CSRF Token:
从浏览器Cookie中读取csrftoken字段的值(Django默认的Cookie名称就是csrftoken)。提交登录请求时携带Token:
发送PUT登录请求时,将Token放到请求头的X-CSRFToken字段中(API场景用请求头比表单隐藏字段更简洁)。
示例代码(React + Axios):
import axios from 'axios'; // 获取CSRF Token const fetchCsrfToken = async () => { await axios.get('/api/login'); // 从Cookie中提取Token const csrfToken = document.cookie.split('; ') .find(row => row.startsWith('csrftoken='))?.split('=')[1]; return csrfToken; }; // 登录操作 const handleLogin = async (username, password) => { const csrfToken = await fetchCsrfToken(); try { const response = await axios.put('/api/login', { username, password }, { headers: { 'X-CSRFToken': csrfToken }, withCredentials: true // 必须开启,确保Cookie被携带到后端 }); console.log('登录成功:', response.data); } catch (error) { console.error('登录失败:', error); } };
额外优化
- 全局配置Axios自动携带CSRF Token,避免每次请求手动处理:
axios.defaults.withCredentials = true; axios.interceptors.request.use(config => { const csrfToken = document.cookie.split('; ') .find(row => row.startsWith('csrftoken='))?.split('=')[1]; if (csrfToken) { config.headers['X-CSRFToken'] = csrfToken; } return config; });
- 后端需在
settings.py中配置跨域信任源,允许前端域名携带Cookie:
CSRF_TRUSTED_ORIGINS = ['https://your-react-domain.com']
内容的提问来源于stack exchange,提问作者sherrellbc
相关产品推荐
相关产品推荐

