You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:30:49