为什么用户密码不在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时,它可能使用的散列函数不是在运行服务器时定义。

+0

您可以在https://docs.djangoproject.com/en/1.4/topics/auth/#how-django-stores-passwords阅读更多关于如何Django的将密码存储或读取整个页面以获得更好地理解Django身份验证如何工作,其中包括用户身份验证。 – miki725

我跑进在我的子类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

+0

您需要扩展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)