通过代理创建的Django用户无法登录

时间:2018-12-01 07:37:42

标签: python django django-models django-rest-framework

我创建了一个继承自 django.contrib.auth.models.User 的模型,并将其扩展为更多字段,然后创建了一个覆盖 save()的代理。哈希密码的方法,但是通过此代理创建的用户无法登录。我跟踪了该过程,发现user.check_password()总是失败,但是我不知道原因。

这是我的模型及其代理:

class UserExtended(User):
    albums = models.ManyToManyField(Album, null=True, blank=True, verbose_name='Albums')

    class Meta:
        verbose_name = _("User")
        verbose_name_plural = _("Users")

    def __str__(self):
        return "[{}] {} ({})({}{})".format(self.id, self.email, self.username, self.first_name, self.last_name)

class UserExtendedProxy(UserExtended):
    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        if not self.id:
            try:
                user = User.objects.get(email=self.email)
            except:
                pass
            else:
                raise Exception('eMail already in use.')

        self.set_password(self.password)
        super(UserExtendedProxy, self).save(*args, **kwargs)
        Token.objects.create(user=self)

这是我的 ModelBackend

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwars):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if user.check_password(password):
                return user

        return None

我可以在数据库中看到通过此代理创建的用户实际上存在于 django.contrib.auth.models.User 模型中,因此我无法弄清为什么他们无法登录

另一个问题是 UserExtendedProxy 不存在通过python manage.py createsuperuser创建的超级用户。

1 个答案:

答案 0 :(得分:0)

他们无法登录,因为您在代理模型中弄乱了他们的密码。您的save()方法中的这段代码将重新散列在self.password中设置的哈希密码值,以使原始密码被破坏:

 self.set_password(self.password)

我不确定您为什么要这么做。 set_password对字符串(纯文本密码)应用哈希算法,以便可以将其保存到数据库。尝试使用已经散列的密码来运行它是没有意义的。

如果您删除该行,密码将不会重新哈希,并且他们应该能够登录。