为什么用户密码不在django admin中被散列?
我使用syncdb
命令创建了一个用户,并且它完全登录。但是,当我创建Django管理用户,它是成功创建,但会导致错误在登录时它,我得到错误:为什么用户密码不在django admin中被散列?
Unknown password hashing algorithm 'password'. Did you specify it in the PASSWORD_HASHERS setting?
有什么问题?如何解决这个问题,以便将用户保存到管理员时自动加密密码?
Django不会将密码存储为纯文本。它首先对它们进行散列,然后它们存储散列。因此,当用户登录时,Django将相同的散列函数应用于用户输入,然后比较这两个散列 - 从用户输入和存储在db中的内容。
但是为了使事情更加灵活,Django不存储密码哈希值,好吧,除此之外,它还存储生成哈希值的算法。想象一下这种情况 - 你使用散列函数X
来生成密码哈希,但是后来你意识到,无论出于何种原因,该函数都不再安全,并且你切换到哈希函数Y
。然而,这是一个问题,因为在任何时候,使用功能X
存储谁是密码散列,他们将无法再登录。这就是为什么除了散列值本身之外,Django还存储生成has的方法。这是设置PASSWORD_HASHERS
的地方。Django存储在db中生成哈希的方法,读取值时,它并不真正告诉Django如何执行哈希函数本身。所以PASSWORD_HASHERS
有点像哈希Python函数(实际上是一个类,但无论如何...)和存储在数据库中的值之间的映射器。
所以回到你的问题。该错误消息意味着Django不知道散列函数password
,它用于将密码的散列存储在数据库中,或者至少不存在于PASSWORD_HASHERS
中。
我能想到为什么会发生这种情况的几个原因。
确保那你就
syncdb
,它使用相同的settings.py
文件,当您正在运行的服务器访问管理的。可能会出现这种情况,即使用不同的设置。但是开发人员通常不会在
settings.py
中修改PASSWORD_HASHERS
,而只是使用默认值。在这种情况下,确保当您执行syncdb
时以及在运行服务器时,您使用的是与Django的安装版本相同的Python。例如,如果您在一个virtualenv中执行syncdb
,并且在不同的env中运行服务器,那么Django版本可能会不同,因此它们可能具有不同的PASSWORD_HASHERS
设置,因此在运行syncdb
时,它可能使用的散列函数不是在运行服务器时定义。
我跑进在我的子类Django的用户的情况相同的问题,那么创建的模型管理它,并使用自动生成的Django管理形式来创建一个用户。
所以我有这样的事情在我的models.py
class Employee(User):
job = models.CharField(max_length=100)
,这在我的管理。py
class EmployeeAdmin(admin.ModelAdmin):
pass
admin.site.register(Employee, EmployeeAdmin)
现在Django自动创建一个用于在Django管理中添加新员工的表单。但是当这个表单用于创建用户时,密码根本不会被散列。因此,出于某种原因,当模型从Django的内置用户派生时,Django为密码创建普通文本输入字段。我不知道你是否有同样的情况。
不幸的是我找不到一个简单的解决方案来解决这个问题。我也不知道为什么Django不会自动为密码创建正确的表单域。然而,有一种可能性是使用包含密码小部件的自定义表单覆盖自动表单。见https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides。
您需要扩展UserAdmin,而不是ModelAdmin –
我遇到了Rubinous答案中显示的相同问题,也可能是您的问题。
问题从django.contrib.admin.ModelAdmin
继承时,我的用户模型来代替django.contrib.auth.admin.UserAdmin
通过这样做,我绕过
密码解决方案被存储为文本而不是哈希密码necesary用户功能使用UserAdmin发生从django.contrib.auth.admin而不是ModelAdmin。
from django.contrib.auth.admin import UserAdmin
class EmployeeAdmin(UserAdmin):
pass
admin.site.register(Employee, EmployeeAdmin)
您可以在https://docs.djangoproject.com/en/1.4/topics/auth/#how-django-stores-passwords阅读更多关于如何Django的将密码存储或读取整个页面以获得更好地理解Django身份验证如何工作,其中包括用户身份验证。 – miki725