Vue.js+Django前后端分离开发遭遇CSRF Origin校验失败问题求助
解决Django DRF + Vue前后端分离的CSRF 403错误及请求体读取问题
一、修复视图中请求体读取的核心错误
你在login视图里直接用json.loads(request.body)会触发内部服务器错误——DRF的request.data已经自动解析了请求体,而CSRF中间件也会读取请求体,重复读取会导致数据流异常。直接改用request.data获取参数即可:
# 替换原有的json解析和KeyError捕获逻辑 email = request.data.get('email') password = request.data.get('password') if not email or not password: return Response("Email or password are missing", status=400)
另外,你把@api_view(['POST'])装饰器用在类视图的方法里是错误用法——api_view仅用于装饰独立函数视图。建议把登录逻辑抽成单独的函数视图:
from rest_framework.decorators import api_view from rest_framework.response import Response from django.contrib.auth import authenticate, login from .serializers import UserSerializer # 独立的登录函数视图(推荐) @api_view(['POST']) def login_view(request): email = request.data.get('email') password = request.data.get('password') if not email or not password: return Response("Email or password are missing", status=400) if not validateEmail(email) or not validatePassword(password): return Response("Invalid email or password format", status=400) user = authenticate(email=email, password=password) if user is None: return Response("Failed to authenticate user", status=400) else: login(request, user) return Response(UserSerializer(user).data)
二、正确配置CSRF信任来源及豁免
1. 基础CSRF配置确认
确保settings.py中的跨域信任配置正确:
CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"] # 本地开发跨域Cookie配置 SESSION_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SAMESITE = 'Lax'
2. 正确豁免CSRF(若需)
如果你的认证方式是Token/JWT而非Session,可直接豁免CSRF:
- 函数视图:直接给视图加装饰器
from django.views.decorators.csrf import csrf_exempt @csrf_exempt @api_view(['POST']) def login_view(request): # 视图逻辑 pass
- 类视图:需要装饰
dispatch方法才能生效
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from rest_framework.views import APIView @method_decorator(csrf_exempt, name='dispatch') class UserAuthenticationView(APIView): serializer_class = UserSerializer def get(self, request): # 获取当前登录用户逻辑 pass def post(self, request): # 注册用户逻辑 pass
你之前在urls中用csrf_exempt(views.UserAuthenticationView.login)无效,是因为login是类内方法,并非独立函数视图,装饰器无法作用于类方法。
三、补全跨域CORS配置
前端跨域请求需后端配合开启CORS支持(先安装django-cors-headers):
# settings.py INSTALLED_APPS = [ # ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... 其他中间件 ] CORS_ALLOWED_ORIGINS = [ "http://localhost:8080", ] CORS_ALLOW_CREDENTIALS = True # 允许携带Cookie
四、APIView的CSRF规则说明
DRF的APIView默认对SessionAuthentication的视图强制CSRF检查;若使用Token/JWT认证,会自动豁免CSRF。你的注册接口出现CSRF错误,说明该视图依赖Session认证,按上述步骤配置CSRF_TRUSTED_ORIGINS和CORS即可解决。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

