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

Django登录接口重复请求出现CSRF缺失403错误求助

问题分析

你遇到的问题根源在于:登录接口调用login()函数后会创建Django Session并返回session cookie,后续请求携带该cookie时,DRF的SessionAuthentication会强制检查CSRF Token,但你的请求未携带该Token,因此触发403错误。虽然添加了@csrf_exempt,但DRF的认证逻辑优先级高于Django的CSRF豁免装饰器,导致豁免未生效。

解决方案

方案1:修改登录视图,禁用DRF的SessionAuthentication检查

通过添加DRF的装饰器,强制禁用该视图的Session认证和权限检查,确保@csrf_exempt生效:

from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import authenticate, login

@csrf_exempt
@api_view(['POST'])
@authentication_classes([])  # 禁用所有认证类,包括SessionAuthentication
@permission_classes([AllowAny])  # 允许任何用户访问
def Userlogin1(request):
    print('login working')
    username = request.data.get('username')
    password = request.data.get('password')
    # 直接使用DRF的request对象,无需调用_request
    user = authenticate(request=request, username=username, password=password)
    if user is not None:
        login(request, user)
        return Response({'message': 'login successful.'}, status=status.HTTP_200_OK)
    return Response(
        {'error': 'Invalid credentials.', 'user': user, 'username': username, 'password': password},
        status=status.HTTP_401_UNAUTHORIZED
    )

方案2:改用无状态认证(推荐)

放弃Django Session登录,使用DRF的TokenAuthentication或JWT,从根源避免Session cookie带来的CSRF问题:

步骤1:配置TokenAuthentication

在settings.py中添加如下配置:

INSTALLED_APPS = [
    # ... 其他已安装应用
    'rest_framework',
    'rest_framework.authtoken',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

运行迁移生成Token数据表:

python manage.py migrate

步骤2:修改登录视图

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token

@api_view(['POST'])
@permission_classes([AllowAny])
def Userlogin1(request):
    username = request.data.get('username')
    password = request.data.get('password')
    user = authenticate(username=username, password=password)
    if user is not None:
        # 获取或创建用户专属Token
        token, created = Token.objects.get_or_create(user=user)
        return Response(
            {'message': 'login successful.', 'token': token.key},
            status=status.HTTP_200_OK
        )
    return Response(
        {'error': 'Invalid credentials.'},
        status=status.HTTP_401_UNAUTHORIZED
    )

后续请求只需在Header中携带Authorization: Token <你的token值>即可完成认证,无需处理CSRF。

方案3:保留Session但携带CSRF Token(不推荐用于登录接口)

如果必须保留Session登录,后续请求需要从Cookie中提取csrftoken值,放到请求Header的X-CSRFToken字段中。在Postman中可开启"Automatically send cookies",并手动添加X-CSRFToken Header,值为Cookie中的csrftoken内容。

内容的提问来源于stack exchange,提问作者Arslan Asghar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 14:04:55