为什么用户密码没有在django admin中进行哈希处理?

时间:2012-09-14 10:50:13

标签: python django admin

我在使用syncdb命令时创建了一个用户,并且完美登录。但是当我从django admin创建用户时,它已成功创建但在登录时会导致错误。我收到错误:

Unknown password hashing algorithm 'password'. Did you specify it in the PASSWORD_HASHERS setting?

问题是什么?如何解决此问题,以便在将用户保存为admin时自动加密密码?

4 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,我已经将Django的用户子类化,然后为它创建了一个模型管理员,并使用自动生成的Django管理表单来创建用户。

所以我在models.py

中有类似的东西
class Employee(User):
    job = models.CharField(max_length=100)

这在我的admin.py

class EmployeeAdmin(admin.ModelAdmin):
    pass
admin.site.register(Employee, EmployeeAdmin)

现在,Django会自动创建一个表单,用于在Django管理员中添加新员工。但是当使用此表单创建用户时,密码根本不会被散列。因此,出于某种原因,当模型从Django的内置User派生时,Django为密码创建了普通的文本输入字段。我不知道你是否有同样的情况。

不幸的是我找不到一个简单的解决方案来解决这个问题。我也不知道为什么Django没有自动为密码创建正确的表单字段。但是,一种可能性是使用包含密码小部件的自定义表单覆盖自动表单。见https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides

答案 1 :(得分:3)

将密码存储为文本而非散列密码的解决方案是使用django.contrib.auth.admin中的UserAdmin而不是ModelAdmin。

from django.contrib.auth.admin import UserAdmin

class EmployeeAdmin(UserAdmin):
    pass

admin.site.register(Employee, EmployeeAdmin)

答案 2 :(得分:2)

我遇到了Rubinous回答中显示的相同问题,也可能是您的问题。

django.contrib.admin.ModelAdmin而不是django.contrib.auth.admin.UserAdmin

继承我的用户模型时发生问题

通过这样做,我绕过了必要的用户功能

答案 3 :(得分:0)

Django不会将密码存储为纯文本。它首先散列它们并存储散列。因此,当用户登录时,Django将相同的哈希函数应用于用户输入,然后比较两个哈希 - 来自用户输入和存储在数据库中的内容。

然而,为了使事情更灵活,Django不存储密码哈希值,但它确实存在密码哈希值,但此外,它还存储了生成哈希值的算法。想象一下这种情况 - 您使用散列函数X来生成密码哈希,但随后您意识到该函数由于某种原因不再是安全的,并且您切换到散列函数Y。然而,这是一个问题,因为在某一点上,无论谁使用函数X存储密码哈希,他们将无法再登录。这就是除了哈希值本身之外,Django还存储生成has的方法的原因。这就是PASSWORD_HASHERS设置的用武之地。事实上Django存储了在db中生成哈希的方法,在读取值时,它并没有真正告诉Django如何执行哈希函数本身。所以PASSWORD_HASHERS有点像散列Python函数(实际上是一个类,但无论如何......)和存储在db中的值之间的映射器。

回到你的问题。错误消息表示Django不知道用于在您的数据库中存储密码哈希的哈希函数password,或者至少不在PASSWORD_HASHERS中。

我可以想到为什么会发生这种情况的几个原因。

  • 确保执行syncdb,它使用与运行服务器访问管理员时相同的settings.py文件。可能是使用不同设置的情况。

  • 但是,开发人员通常不会修改PASSWORD_HASHERS中的settings.py,只使用默认值。在这种情况下,当您执行syncdb和运行服务器时,请确保使用与安装版本相同的Django相同的Python。例如,如果您在一个virtualenv中执行syncdb并在不同的env中运行服务器,则Django版本可能会有所不同,因此它们可能具有PASSWORD_HASHERS的不同设置,因此您运行的位置{{1}它可能正在使用一个在运行服务器时未定义的散列函数。