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

Django自定义用户模型登录失败:check_password验证不通过

Django自定义用户模型登录失败:check_password验证不通过

看起来你在自定义Django用户模型时遇到了登录密码验证失败的问题,我帮你梳理下核心原因和修复方案,应该能解决你的问题!

问题核心原因

你提到用了password_strength库的make_password来哈希密码,但登录时用的check_password大概率是Django自带的工具——这两个不同库的密码哈希/验证逻辑不兼容,自然会导致“密码无效”的错误。另外,直接给password字段手动赋值哈希值的方式,也不是Django推荐的标准做法,容易踩坑。

具体修复步骤

1. 改用Django配套的密码工具

Django自身的django.contrib.auth.hashers模块提供了完全兼容的make_password和check_password,先确保你导入的是这两个:

from django.contrib.auth.hashers import make_password, check_password

2. 用用户模型的set_password()方法设置密码(推荐)

不管是默认用户模型还是自定义模型,只要继承了AbstractBaseUser,就自带set_password()方法——这个方法会自动帮你处理密码哈希,比手动调用make_password更规范,也能避免哈希/验证不兼容的问题。

修改你的注册代码:

@csrf_exempt
def signin_attempt(request):
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            email = data.get('email')
            password = data.get('password')
            username = data.get('username')
            stats = PasswordStats(password)

            validations = {
                "Password must be at least 8 characters long and contain at least one number and one special character":
                    bool(policy.test(password)),
                "Password is too weak": stats.strength() < 0.5,
                "Username already exists": user.objects.filter(username=username).exists(),
                "Email already exists": user.objects.filter(email=email).exists(),
            }

            for message, condition in validations.items():
                if condition:
                    return JsonResponse({'success': False, 'message': message}, status=400)

            # 先创建用户实例,不直接赋值password
            user_obj = user(username=username, email=email)
            # 用set_password自动处理哈希
            user_obj.set_password(password)
            user_obj.save()
            
            return JsonResponse({'success': True, 'message': "Sign in successful"}, status=201)

        except Exception as e:
            return JsonResponse({'success': False, 'message': f"Error: {str(e)}"}, status=500)

    return JsonResponse({'success': False, 'message': "Invalid request method"}, status=405)

3. 检查自定义用户模型的继承结构

确保你的user模型正确继承了Django的基类,这是set_password和check_password能正常工作的前提:

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

class MyUserManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError("Users must have an email address")
        user = self.model(
            email=self.normalize_email(email),
            username=username,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=100, unique=True)
    # 你的其他自定义字段...

    objects = MyUserManager()

    USERNAME_FIELD = 'email'  # 设置邮箱为登录标识
    REQUIRED_FIELDS = ['username']

4. 确保登录代码用的是Django的check_password

你的登录代码逻辑没问题,只要check_password是从django.contrib.auth.hashers导入的,验证就能正常通过。

额外小建议

  • 尽量不要用@csrf_exempt,可以在前端传递CSRF令牌,或者改用csrf_protect装饰器,提升接口安全性;
  • 自定义模型类名建议用大驼峰(比如User而非user),符合Python的命名规范,也避免和内置名称冲突。

备注:内容来源于stack exchange,提问作者Aalok karn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:38:10