【问题标题】:why django user password doesnt encrypted while i create new user?为什么我创建新用户时 django 用户密码没有加密?
【发布时间】:2020-03-03 20:26:43
【问题描述】:

我正在尝试使用AbstractUser 类制作我自己的自定义用户模型

class CustomUser(AbstractUser):
    is_student = models.BooleanField(default=False)
    is_teacher = models.BooleanField(default=False)

    def __str__(self):
        return self.username

class Student(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

但是当我创建新帐户时,密码字段不会被加密,它只显示纯文本! 我想我应该使用BaseUserManager,但我不知道怎么做 谢谢,问候..

【问题讨论】:

  • 欢迎来到 Stackoverflow @art_cs。你能告诉我你是如何创建新用户的吗?
  • 来自 admin url ,我将使用屏幕截图更新帖子
  • 您是否也更改了CustomUser 的管理员?如果是,请也分享代码。
  • 不,只有这一行 (admin,site.register) 全部
  • 你的自定义用户admin也必须继承自Django的UserAdmin。检查我的答案。

标签: python django model


【解决方案1】:

由于我不完全知道你是如何创建新用户的,我猜你正在做类似的事情,

user = CustomUser.objects.create(username="boohoo", email="boo@hoo.com", password="boohoopass")

此用户对象将密码存储为纯文本。 Django 不会自动将文本转换为散列值,相反,如果您深入挖掘,您会发现一个名为make_password 的方法,或者在AbstractUserset_password 中有一个方法基本上将字符串转换为散列值。因此,当您创建用户时,请使用这两种方法中的任何一种。

user = CustomUser.objects.create(username="boohoo", email="boo@hoo.com")

user.passowrd = make_password("boohoopass")

# or 

user.set_password("boohoopass")

更好的方法是使用UserManagercreate_user 中的方法,它会自动为您执行此操作。

user = CustomUser.objects.create_user(username="boohoo", email="boo@hoo.com", password="boohoopass")

更新 在您的情况下,您的管理类还必须从 django 的 UserAdmin 继承。因为用户 admin 还调用了特定的函数来制作密码哈希键之类的东西。

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as OrigUserAdmin


@admin.register(CustomUser)
class CustomUserAdmin(OrigUserAdmin):
    list_display = (
        'id', 'first_name', 'last_name', 'username', 'email', 'is_active'
    )

【讨论】:

  • 我会尝试制作 UserManager 类,我不知道如何制作!我只添加了两个额外的字段,这就是为什么我不知道如何在 UserManager 类中管理它们,感谢您的帮助
  • 已经存在,它是AbstractUser 类的一部分。检查 AbstractUser 类的第 326 行(希望如此),它定义了 objects = UserManager()
  • 我还将 objects = UserManager() 添加到 CustomUser 但仍然不会加密!
  • @art_cs 您不必这样做,因为经理已经是AbstractUser 的一部分,请检查我答案的更新部分。我认为您的问题在于管理员。
【解决方案2】:

我相信你必须自己加密密码。

一个简单的方法是使用像密码学这样的库 你可以用pip install cryptography安装它


from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
tasty_salt = b'some tasty salt to help us digest that password'
def hashPassword(password):
  digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
  digest.update(str.encode(password))
  digest.update(tasty_salt)
  return digest.finalize()


def verifyPassword(input_password,hashed_password):#get hashed_password from your user model
  digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
  digest.update(str.encode(input_password))
  digest.update(tasty_salt)
  return digest.finalize() == hashed_password

print(verifyPassword('password',hashPassword('password')))

这将让您在用户模型中散列密码。只需将其导入您的项目,您就可以开始使用了。

【讨论】:

    【解决方案3】:

    您可以使用保存方法来加密自定义用户模型的密码。 使用以下代码创建加密密码的 AbstractUser 方法:

    class CustomModel(AbstractUser):
        .......
        
        def save(self):
            user = super(CustomModel, self)
            user.set_password(self.password)
            user.save()
            return user
    

    【讨论】:

      猜你喜欢
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多