Django CSRF验证失败:配置正确令牌仍报403错误
已在POST请求中携带正确CSRF令牌、遵循官方步骤,但仍收到“CSRF Missing”403错误,请求头已包含X-CSRFToken和Cookie。以下是当前配置及排查建议:
当前配置
Axios 配置
const service = axios.create({ baseURL, timeout: 4000, withCredentials: true, xsrfCookieName: 'csrftoken', xsrfHeaderName: 'X-CSRFToken', }); ... headers: { 'X-CSRFToken': Cookies.get('csrftoken'), },
Django 配置
# settings.py CSRF_COOKIE_NAME = 'csrftoken' CSRF_HEADER_NAME = 'X-CSRFToken' CSRF_TRUSTED_ORIGINS = [ 'http:127.0.0.1:5173' ] CORS_ALLOW_CREDENTIALS = True @ensure_csrf_cookie def get_csrf_token(request): request.META["CSRF_COOKIE_USED"] = True return JsonResponse({'msg': 'now csrftoken has been set in ur Cookies'})
排查建议
修正
CSRF_TRUSTED_ORIGINS格式
当前配置的'http:127.0.0.1:5173'缺少斜杠,正确格式应为'http://127.0.0.1:5173',格式错误会导致信任源不生效,Django无法识别跨域请求的合法性。检查令牌获取时机与一致性
确保发送POST请求前已调用get_csrf_token接口设置Cookie,且浏览器控制台中Cookies.get('csrftoken')的值与请求头X-CSRFToken完全一致,避免令牌过期或手动获取时的取值错误。移除Axios重复配置
同时在axios.create和请求headers中设置CSRF令牌可能导致冲突,建议去掉手动设置的headers部分,让Axios自动从Cookie读取并注入请求头:const service = axios.create({ baseURL, timeout: 4000, withCredentials: true, xsrfCookieName: 'csrftoken', xsrfHeaderName: 'X-CSRFToken', });调整CSRF Cookie属性
开发环境下,避免设置CSRF_COOKIE_SECURE = True(仅HTTPS环境生效),同时将CSRF_COOKIE_SAMESITE设为Lax,防止跨域时Cookie无法携带:# settings.py CSRF_COOKIE_SAMESITE = 'Lax' # 生产环境HTTPS时再开启以下配置 # CSRF_COOKIE_SECURE = True验证中间件与视图装饰器
确认django.middleware.csrf.CsrfViewMiddleware在MIDDLEWARE配置中存在,且顺序在SessionMiddleware之后、CommonMiddleware之前;同时检查处理POST请求的视图未误用csrf_exempt装饰器跳过验证。用curl做极简测试
先获取CSRF Cookie:curl -c cookies.txt http://127.0.0.1:8000/get-csrf-token/再发送POST请求:
curl -b cookies.txt -H "X-CSRFToken: $(grep csrftoken cookies.txt | awk '{print $7}')" -X POST http://127.0.0.1:8000/your-post-endpoint/ -d "test=1"若curl请求成功,问题出在前端Axios配置;若失败,则后端配置或视图存在问题。
内容的提问来源于stack exchange,提问作者Kevin Kwok

