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

Django登录接口返回Invalid email or password错误排查与修复求助

登录功能错误排查与修复

问题现象

实现账号登录时,系统返回错误:{"error": "Invalid email or password"},但已通过管理后台确认邮箱与密码均正确。

核心问题分析

从代码来看,主要有以下几个关键问题导致认证失败:

  1. 自定义User模型未正确实现密码哈希
    你的User模型直接用CharField存储password,但Django的authenticate函数是基于哈希密码进行验证的。如果密码未经过哈希存储(比如直接赋值而非调用set_password),验证必然失败。

  2. 认证参数不匹配默认后端规则
    默认的Django认证后端(ModelBackend)仅识别username和password参数,而你的LoginView中使用了authenticate(request, email=email, password=password),email参数无法被默认后端识别,导致无法找到用户。

  3. 自定义User模型未配置登录标识字段
    未设置USERNAME_FIELD = 'email',认证后端无法将邮箱作为登录的唯一标识,即便传入邮箱作为username参数,也无法正确匹配用户。

  4. LoginSerializer未被实际调用
    LoginView的post方法直接从request.data取值,没有使用定义好的LoginSerializer做验证,相当于白写了序列化器的逻辑。

修复步骤

1. 修正自定义User模型

继承AbstractBaseUser和PermissionsMixin,实现密码哈希功能,并设置邮箱为登录标识:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('必须填写邮箱')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)  # 自动哈希密码
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=255, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'  # 设置邮箱为登录标识
    objects = UserManager()

2. 配置自定义User模型

在项目的settings.py中添加:

AUTH_USER_MODEL = '你的应用名.User'  # 替换为实际的应用名称

3. 修复LoginView的认证逻辑

选择以下两种方式之一:

方式一:使用LoginSerializer处理验证

def post(self, request):
    serializer = self.serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    user = serializer.validated_data['user']
    login(request, user)
    token, created = Token.objects.get_or_create(user=user)
    return Response({'token': token.key}, status=status.HTTP_200_OK)

方式二:直接修正authenticate参数

def post(self, request):
    email = request.data.get('email')
    password = request.data.get('password')
    # 用username参数传入邮箱,匹配USERNAME_FIELD设置
    user = authenticate(request, username=email, password=password)
    if user is not None:
        login(request, user)
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key}, status=status.HTTP_200_OK)
    return Response({'error': 'Invalid email or password'}, status=status.HTTP_401_UNAUTHORIZED)

4. 确保密码哈希存储

无论是通过admin后台还是代码创建用户,都要确保密码经过哈希:

  • 代码创建用户时,必须调用user.set_password(password)而非直接赋值user.password = password
  • admin后台创建用户时,Django会自动处理哈希,无需额外操作

验证修复

  1. 重新迁移数据库:python manage.py makemigrations + python manage.py migrate
  2. 创建新用户(或重置现有用户密码,确保密码被哈希)
  3. 测试登录接口,确认返回正常的token

内容的提问来源于stack exchange,提问作者Zero Xefon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:35:39