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

Django自定义AbstractUser模型登录验证失败问题求助

问题分析与解决

核心原因

你遇到的问题本质是注册时没有对用户密码进行哈希加密,直接将明文密码存入了数据库。而Django的authenticate()方法验证时,会将传入的明文密码用默认哈希算法处理后,与数据库中存储的哈希值对比——如果数据库里是明文,对比必然失败,返回None。

而admin后台修改密码时,Django会自动调用User.set_password()方法完成密码加密,所以修改后的用户能正常登录。

解决步骤

1. 修正注册代码

将直接赋值password的逻辑,替换为调用set_password()方法:

错误的注册代码(直接存明文):

from yourapp.models import CustomUser

def register(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')
        # 错误:直接赋值password字段,存明文
        user = CustomUser.objects.create(
            email=email,
            password=password
        )
        # ...其他逻辑

修正后的代码(加密存储):

from yourapp.models import CustomUser

def register(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')
        # 先创建用户(不设置password)
        user = CustomUser.objects.create(
            email=email
        )
        # 调用set_password加密密码
        user.set_password(password)
        # 必须再次保存到数据库
        user.save()
        # ...其他逻辑

2. 修复已存在的明文密码用户

如果数据库中已有注册的明文密码用户,可以通过Django Shell批量修复:

# 执行 python manage.py shell 进入交互环境
from yourapp.models import CustomUser

for user in CustomUser.objects.all():
    # 未加密的密码不会以默认哈希前缀开头
    if not user.password.startswith('pbkdf2_sha256$'):
        user.set_password(user.password)  # 用原明文密码重新加密
        user.save()

也可以让用户通过密码重置流程重新设置密码。

底层逻辑说明

  • Django的AbstractBaseUser(AbstractUser继承自它)的password字段专门用于存储哈希后的密码字符串,而非明文。
  • set_password()方法会根据settings.py中PASSWORD_HASHERS配置的算法(默认是django.contrib.auth.hashers.PBKDF2PasswordHasher),对明文密码进行加盐哈希处理,生成安全的哈希字符串。
  • authenticate()方法验证时,会取出数据库中的哈希值,解析出盐和算法,然后对传入的明文密码做相同的哈希处理,最后对比两个哈希值是否一致——一致则返回用户对象,否则返回None。

内容的提问来源于stack exchange,提问作者s-knocks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:55:20