Django自定义用户模型认证失败:密码哈希验证不通过
密码重复哈希导致登录认证失败的原因与解决方案
核心原因
你碰到的问题确实是密码重复哈希导致的:
make_password()已经将原始密码转换成不可逆的哈希值- 而
UserManager.create_user()内部的set_password()方法,会再次对传入的字符串(此时已是哈希值)执行哈希操作 - 最终数据库存储的是「哈希的哈希」,用原始密码调用
check_password()自然返回False
单独测试时仅做了一次哈希,所以验证正常;但注册流程里做了两次哈希,导致匹配失败。
解决方法
方法1:修改注册逻辑(推荐)
直接将原始密码传给 create_user(),不要提前调用 make_password(),让 set_password() 完成哈希处理:
# 错误写法 raw_password = "your_raw_password" hashed_pw = make_password(raw_password) user = User.objects.create_user(email="user@example.com", password=hashed_pw) # 正确写法 raw_password = "your_raw_password" user = User.objects.create_user(email="user@example.com", password=raw_password)
方法2:修改UserManager逻辑(特殊场景使用)
如果必须提前处理密码,可在 create_user() 中判断传入的是否为有效哈希值,避免重复哈希:
from django.contrib.auth.base_user import BaseUserManager from django.contrib.auth.hashers import is_password_usable class UserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): # 邮箱格式化等基础逻辑 user = self.model(email=self.normalize_email(email), **extra_fields) if password: # 检查是否为已哈希密码,是则直接赋值,否则调用set_password if is_password_usable(password): user.password = password else: user.set_password(password) user.save(using=self._db) return user
额外检查:确认自定义认证后端逻辑
确保认证后端正确通过邮箱查询用户,示例如下:
from django.contrib.auth.backends import ModelBackend from django.contrib.auth import get_user_model User = get_user_model() class EmailAuthenticationBackend(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_app.backends.EmailAuthenticationBackend', 'django.contrib.auth.backends.ModelBackend', ]
内容的提问来源于stack exchange,提问作者crawlingdev
相关产品推荐
相关产品推荐

