You need to enable JavaScript to run this app. Django自定义AbstractBaseUser模型authenticate登录验证失败如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义AbstractBaseUser模型authenticate登录验证失败如何解决?

问题根因&解决步骤

1. 模型字段定义错误

你自定义的User模型重写了AbstractBaseUser已经自带的password字段,并且把max_length设为25:

# 这行代码是错误的,直接删掉
password = models.CharField(max_length = 25)

Django的密码加密后长度远大于25位,直接截断会导致密码哈希值损坏,校验永远失败。AbstractBaseUser已经内置了符合要求的password字段,不需要自己定义。
同时你的is_active字段默认值为False,Django默认的authenticate方法只会返回is_active=True的用户,如果你没有手动修改用户激活状态,校验也会失败。如果你的业务逻辑允许用户注册后直接登录,可以把默认值改为True:

is_active = models.BooleanField(default = True)

2. 密码存储方式错误

你自己遍历对比明文密码能成功,说明你创建用户时直接存储了明文密码,没有做加密处理。authenticate方法会自动把传入的明文密码加密后,和数据库存储的哈希值对比,两者当然匹配不上。
创建用户时必须使用set_password()方法处理明文密码,或者调用自定义管理器的create_user方法,禁止直接给password字段赋值明文:

# 错误写法,禁止使用
user = User(username="xxx", password="123456")
user.save()

# 正确写法1:手动调用set_password
user = User(username="xxx", email="xxx@xx.com", phone="13xxxxxxxxx", first_name="xx", last_name="xx")
user.set_password("你的明文密码") # 这一步会自动加密密码
user.save()

# 正确写法2:调用create_user方法(需要你的管理器正确实现)
user = User.objects.create_user(
    username="xxx",
    email="xxx@xx.com",
    phone="13xxxxxxxxx",
    first_name="xx",
    last_name="xx",
    password="你的明文密码"
)

3. 检查自定义管理器实现

你的UserProfileManager必须继承BaseUserManager,并且正确实现create_user、create_superuser方法,内部必须调用set_password处理密码,示例如下:

from django.contrib.auth.base_user import BaseUserManager

class UserProfileManager(BaseUserManager):
    def create_user(self, username, email, phone, first_name, last_name, password=None):
        if not email:
            raise ValueError('用户必须提供邮箱')
        email = self.normalize_email(email)
        user = self.model(
            username=username,
            email=email,
            phone=phone,
            first_name=first_name,
            last_name=last_name
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, username, email, phone, first_name, last_name, password):
        user = self.create_user(
            username=username,
            email=email,
            phone=phone,
            first_name=first_name,
            last_name=last_name,
            password=password
        )
        user.is_staff = True
        user.is_superuser = True
        user.is_active = True
        user.save(using=self._db)
        return user

4. 生效修改

所有代码修改完成后,执行迁移命令更新数据库:

python manage.py makemigrations
python manage.py migrate

注意:之前已经存入数据库的用户密码都是无效的,需要重新创建用户或者调用set_password重新设置密码才能正常登录。

修改完成后你原本的authenticate逻辑就可以正常运行,登录后会自动写入用户会话,@login_required装饰器也会正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 20:27:04