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

DRF中authenticate()返回None问题排查与解决求助

Django REST Framework登录认证失败问题排查

我使用Django REST Framework开发,注册功能正常,但登录时传入正确的邮箱和密码后,authenticate()始终返回None,且执行CustomUser.objects.get(email=email)也无法获取用户实例。相关代码如下:

models.py(部分字段)

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password, **kwargs):
        if not email:
            raise ValueError('The user must enter a valid email.')
        email = self.normalize_email(email)
        user = self.model(email=email, **kwargs)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **kwargs):
        kwargs.setdefault('is_staff', True)
        kwargs.setdefault('is_superuser', True)
        kwargs.setdefault('is_active', True)

        if kwargs.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if kwargs.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self.create_user(email, password, **kwargs)

class CustomUser(AbstractBaseUser, PermissionsMixin):
    user_id = models.AutoField(primary_key=True)

    first_name = models.CharField(max_length=255, blank=True)
    middle_name = models.CharField(max_length=255, blank=True)
    last_name = models.CharField(max_length=255, blank=True)

    email = models.EmailField(unique=True)

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    groups = models.ManyToManyField(
        "auth.Group",
        related_name="customuser_set",
        blank=True
    )
    user_permissions = models.ManyToManyField(
        "auth.Permission",
        related_name="customuser_set",
        blank=True
    )

viewsets.py

@action(detail=False, methods=["post"], permission_classes=[AllowAny])
def login(self, request):
    email = request.data.get("email")
    password = request.data.get("password")
    user = CustomUser.objects.get(email=email)
    print(user)
    user = authenticate(request, email=email, password=password) # 始终返回None
    if user:
        login(request, user)
        return Response({"message": "Login successful!"})
    return Response({"error": "Invalid credentials"}, status=401)

settings.py

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

问题排查与解决方案

  1. 配置AUTH_USER_MODEL
    Django默认使用内置User模型,若未指定自定义用户模型,注册的用户会存入错误表,导致认证时找不到数据。在settings.py中添加:

    AUTH_USER_MODEL = '你的应用名.CustomUser'
    

    替换你的应用名为自定义用户模型所在的App名称。

  2. 重新执行数据库迁移
    中途修改自定义用户模型可能导致表结构异常,按以下步骤重置:

    • 删除App下migrations目录中除__init__.py外的所有文件
    • 删除数据库(或清空用户相关表)
    • 重新执行迁移:
      python manage.py makemigrations
      python manage.py migrate
      

    完成后重新注册用户测试登录。

  3. 标准化邮箱格式
    注册时CustomUserManager会将邮箱转为小写,但登录传入的邮箱可能存在大小写差异,导致查询失败。在登录视图中添加标准化处理:

    email = request.data.get("email")
    if email:
        email = CustomUser.objects.normalize_email(email)
    
  4. 检查用户状态与认证参数

    • 确保用户的is_active字段为True,ModelBackend会拒绝认证未激活用户
    • 尝试简化authenticate调用,去掉request参数:
      user = authenticate(email=email, password=password)
      
  5. 验证数据库数据
    直接查询数据库确认对应邮箱的用户是否存在,排除注册逻辑未正确写入数据的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:33:19