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

Django登录API问题:Postman请求报错且user打印返回None

问题分析与修复方案

核心问题点

  1. 请求方法错误:使用GET请求提交登录数据,request.data无法获取POST体中的参数,且GET请求会将密码暴露在URL中,存在安全风险。
  2. 认证逻辑错误:Django默认的authenticate方法通过username和password验证身份,而非email,直接传入email=email无法匹配用户。
  3. 序列化器字段问题:password字段未设置write_only=True,导致无法正确获取输入的密码值;且应使用validated_data而非data获取验证后的参数。

具体修复步骤

1. 修改视图类的请求方法与认证逻辑

将get方法改为post,并调整用户认证的逻辑:

class UserLoginView(APIView):
    permission_classes = (AllowAny,)
    serializer_class = UserLoginSerializer
    
    # 替换get为post方法,符合登录请求的语义
    def post(self, request, format=None):
        serializer = UserLoginSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            # 使用validated_data获取验证后的参数,比data更可靠
            email = serializer.validated_data.get('email')
            password = serializer.validated_data.get('password')
            
            # 先通过邮箱查询对应用户
            try:
                user = User.objects.get(email=email)
            except User.DoesNotExist:
                return Response({'msg': 'Email or Password Does not match'}, status=status.HTTP_404_NOT_FOUND)
            
            # 用username和密码执行认证
            authenticated_user = authenticate(username=user.username, password=password)
            if authenticated_user is not None:
                login(request, authenticated_user)
                return Response({'msg': 'Login Success'}, status=status.HTTP_200_OK)
            else:
                return Response({'msg': 'Email or Password Does not match'}, status=status.HTTP_404_NOT_FOUND)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

2. 修正序列化器的密码字段

显式设置password为只写字段,确保能正确接收输入的密码:

class UserLoginSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(max_length=200)
    # 设置password为只写字段,避免序列化返回密码,同时确保能获取输入值
    password = serializers.CharField(write_only=True)
    
    class Meta:
        model = User
        fields = ['email', 'password']

3. Postman请求调整

  • 请求方法改为POST
  • 请求体选择raw -> JSON,输入格式示例:
{
    "email": "test@example.com",
    "password": "your-password"
}

可选优化:自定义邮箱认证后端(推荐)

如果希望直接用邮箱+密码认证,无需手动查询用户,可以自定义认证后端:

在项目根目录创建backends.py文件:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 用传入的username参数匹配邮箱
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            return None
        # 验证密码正确性
        if user.check_password(password):
            return user
        return None

在settings.py中配置认证后端:

AUTHENTICATION_BACKENDS = [
    'your_project_name.backends.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',
]

此时视图中的认证逻辑可简化为:

user = authenticate(request, username=email, password=password)

内容的提问来源于stack exchange,提问作者Yashraj Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:05:40