Django测试API创建用户时遇CSRF token缺失错误,该如何处理?
解决Django API CSRF验证失败问题
错误原因
你遇到的"detail": "CSRF Failed: CSRF token missing."错误,是因为Django默认对POST、PUT等非安全请求启用CSRF保护,防范跨站请求伪造攻击。
能否移除CSRF验证?
可以,但需分场景处理:
- 纯API服务场景(如前后端分离、第三方调用):
- 方法1:给单个视图添加
@csrf_exempt装饰器from django.views.decorators.csrf import csrf_exempt from django.http import JsonResponse @csrf_exempt def create_user(request): if request.method == 'POST': # 处理用户创建逻辑 return JsonResponse({"status": "success"}) - 方法2:使用Django REST Framework的
APIView,它默认对API请求不强制CSRF验证(DRF默认假设API使用Token/JWT等认证方式)from rest_framework.views import APIView from rest_framework.response import Response class CreateUserAPI(APIView): def post(self, request): # 处理用户创建逻辑 return Response({"status": "success"}) - 注意:如果是普通Django模板渲染的视图,不建议移除CSRF验证,会引入安全风险。
- 方法1:给单个视图添加
测试环境传递CSRF Token的方法
- Cookie提取+请求头传递:
- 先发送GET请求到任意Django页面(如
/),从响应Cookie中提取csrftoken值 - 在POST请求头中添加
X-CSRFToken: 提取到的token值 - curl示例:
# 先获取CSRF token并存入cookie文件 curl -c cookies.txt http://localhost:8000/ # 携带cookie和token发送POST请求 curl -b cookies.txt -H "X-CSRFToken: 替换为提取的token" -X POST -d "username=test&password=123" http://localhost:8000/api/create-user/
- 先发送GET请求到任意Django页面(如
- Django测试客户端自动处理:
编写测试用例时,Django的Client会自动管理CSRF token:from django.test import Client client = Client() response = client.post('/api/create-user/', {'username': 'test', 'password': '123'})
生产环境传递CSRF Token的方法
- 前后端同域场景:
- 前端从Cookie中读取
csrftoken,在发送非GET请求时,将其放入X-CSRFToken请求头 - JavaScript示例:
function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); fetch('/api/create-user/', { method: 'POST', headers: { 'X-CSRFToken': csrftoken, 'Content-Type': 'application/json' }, body: JSON.stringify({username: 'test', password: '123'}) });
- 前端从Cookie中读取
- 前后端分离(跨域)场景:
- 配置
django-cors-headers处理跨域请求 - 设置
CSRF_COOKIE_SAMESITE = 'Lax'(或'None',适用于跨域HTTPS场景),同时生产环境HTTPS下需设CSRF_COOKIE_SECURE = True - 前端请求需携带
withCredentials: true,并传递X-CSRFToken头
- 配置
关于CSRF_COOKIE_SECURE的说明
该设置仅控制CSRF Cookie是否仅在HTTPS连接下发送,设为false不解决token缺失问题——你仍需正确传递token,或对目标视图禁用CSRF验证。
内容的提问来源于stack exchange,提问作者Matteo Possamai
相关产品推荐
相关产品推荐

