Django+React项目POST请求遇CSRF源验证失败错误求助
问题描述
我使用Django作为后端、RestAPI进行数据传输、ReactJs作为前端开发Web应用。发送表单数据的POST请求时,出现错误:
"CSRF Failed: Origin checking failed - http://localhost:8000/ does not match any trusted origins."
Django能识别请求但拒绝了该请求。React使用代理与服务器交互,我已查阅相关解决帖但均未解决问题。
React请求代码
const item = {tittle : data.target.tittle.value, description : data.target.description.value}; axios({ headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, method : "post", url : "api/articles/", data : item }).catch((e) => {console.log(e)})
Django settings.py配置
CSRF_TRUSTED_ORIGINS = [ 'http://localhost:8000' ] ALLOWED_HOSTS = [ 'localhost', ] CORS_ORIGIN_WHITELIST = [ 'http://localhost:8000', ] CORS_ORIGIN_ALLOW_ALL = True
Django views.py处理类
class ArticleList(generics.ListCreateAPIView): def post(self, request, format=None): serializer = ArticleSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def get(self, request, format=None): snippets = Articles.objects.all() serializer = ArticleSerializer(snippets, many=True) return Response(serializer.data)
解决方案
1. 修正信任源配置
React默认运行端口是3000,你当前配置的信任源都是Django的8000端口,这是核心错误。把前端实际运行的地址加入信任列表:
# settings.py CSRF_TRUSTED_ORIGINS = [ 'http://localhost:3000' ] ALLOWED_HOSTS = [ 'localhost', ] CORS_ORIGIN_WHITELIST = [ 'http://localhost:3000' ] # 建议关闭CORS_ORIGIN_ALLOW_ALL,避免覆盖白名单配置 CORS_ORIGIN_ALLOW_ALL = False
2. 在请求中携带CSRF令牌
Django的CSRF验证要求请求头携带X-CSRFToken,修改React代码如下:
// 从Cookie中提取CSRF令牌 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 item = {tittle : data.target.tittle.value, description : data.target.description.value}; const csrftoken = getCookie('csrftoken'); axios({ headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, method : "post", url : "api/articles/", data : item }).catch((e) => {console.log(e)})
3. 检查Django中间件顺序
确保settings.py的MIDDLEWARE包含以下两个中间件,且顺序正确:
MIDDLEWARE = [ # ...其他中间件 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.common.CommonMiddleware', # ...其他中间件 ]
4. 临时测试方案(不推荐生产)
如果只是快速测试,可以给视图类添加csrf_exempt装饰器跳过验证,但生产环境禁止使用:
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class ArticleList(generics.ListCreateAPIView): # ...你的视图代码
内容的提问来源于stack exchange,提问作者nyar
相关产品推荐
相关产品推荐

