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

标签 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 模型中,所以我无法弄清楚为什么他们无法登录.

另一个问题是,通过 python manage.py createsuperuser 创建的 super 用户对于 UserExtendedProxy 不存在。

最佳答案

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

 self.set_password(self.password)

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

如果您删除该行,密码将不会被重新散列,他们应该能够登录。

关于python - 通过代理创建的Django用户无法登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53568782/

相关文章:

python - 关闭请求库中的代理

python - Django Windows 身份验证

postgresql - Django ORM 保留打开的连接

python - 将包含 8 个以上类的模块拆分为一个包,每个类都在自己的文件中

python - 获取具有大于指定值的不同值的列名称python

python - mod_wsgi 测试 wsgi 运行良好,应用程序给出 HTTP 500

python - 尝试将通过social_django验证的用户添加到组时出现错误 `set object is not subscriptable`

python - 为什么 Heroku 在新部署中安装旧的 Python (pip) 依赖项?

python - Django - 在创建或更新查询中使用模型字段部分

python - 如何扩展 Django Group 模型?