如何在没有用户对象的情况下存储 Django 散列密码?

Posted

技术标签:

【中文标题】如何在没有用户对象的情况下存储 Django 散列密码?【英文标题】:How to store Django hashed password without the User object? 【发布时间】:2014-09-25 17:36:24 【问题描述】:

我有一个 Django 应用程序,它允许网络访问者在那里创建自己的帐户。一旦他们使用密码创建了一个帐户,他们应该会收到包含激活码的电子邮件。当网络访问者创建一个新帐户时,他们需要收到一封包含唯一密钥的激活电子邮件。

显然,我可以使用 Django 的内置身份验证系统来完成所有这些工作。我以前做过,没有任何问题。但是,在这个应用程序中,我不想让非活动用户污染我的用户表。我只希望激活的用户出现在用户表中。因此,虽然我将使用 Django 的帐户系统来验证激活的用户,但在他们被激活之前,我正在滚动我自己的系统。我将有关尚未激活的用户的所有数据保存在一个单独的 Django 模型对象(称为UserActivation)中。我将自己管理激活电子邮件的发送。

我遇到的问题是我不想以纯文本形式存储用户提交的密码。我想将它存储在我的 UserActivation 对象中的一个名为“密码”的字段中,其散列格式与它将出现在用户表中的哈希格式相同。要将其放入用户对象,我会做myUser.set_password("plainTextPassword")。如何获得相同的值并将其填充到 UserActivation.password

通过查看this 文档,似乎有一个make_password() 函数可以返回我需要的值。但我仍然需要一个用户对象来调用该方法。如何在不通过 User 对象的情况下将 "plainTextPassword" 转换为哈希密码?

【问题讨论】:

【参考方案1】:

你在正确的轨道上。但是,您可以使用手动管理密码

from django.contrib.auth.hashers import make_password
print "Hashed password is:", make_password("plain_text")

Hasher 配置将由 PASSWORD_HASHERS 驱动,这对于身份验证系统和您的 UserActivation 模型应该是通用的。但是你也可以在make_password 方法中传递它。

PASSWORD_HASHERS = (
    'myproject.hashers.MyPBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

希望这会有所帮助。

阅读此链接了解更多详情: https://docs.djangoproject.com/en/dev/topics/auth/passwords/

【讨论】:

【参考方案2】:

接受的答案对我很有帮助 - 我只是想添加 check_password 调用(对于像我这样以前没有使用过此功能的人)

from django.contrib.auth.hashers import make_password, check_password

hashed_pwd = make_password("plain_text")
check_password("plain_text",hashed_pwd)  # returns True

【讨论】:

小点要注意,即使 pw 为 None,make_password 也会返回一个字符串(尽管对于内置登录无效)。内置登录检查是否以 UNUSABLE_PASSWORD_PREFIX 常量开头。【参考方案3】:

我最近通过以下步骤解决了这个问题:

from .models import Client
from django.contrib.auth.hashers import make_password
from .forms import ClientForm

form =  ClientForm(request.POST)

if form.is_valid():
    
            first_name      = form.cleaned_data['first_name']
            family_name     = form.cleaned_data['family_name']
            password        = make_password(form.cleaned_data['password'])
            phone           = form.cleaned_data['phone']
            
            user    =   Client(first_name=first_name, family_name=family_name, password=password, phone=phone)
            user.save()

【讨论】:

以上是关于如何在没有用户对象的情况下存储 Django 散列密码?的主要内容,如果未能解决你的问题,请参考以下文章

django 自定义用户模型密码没有被散列

如何在没有确认的情况下使用 django migrate

哈希表调整大小:我们如何在不知道密钥的情况下做到这一点?

Django:密码格式无效或散列算法未知

在没有文件扩展名的情况下返回 Django 中的文件路径

我们如何在没有列表理解的情况下在 m2m 字段的 django 管理面板中显示用户