如何在没有用户对象的情况下存储 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 散列密码?的主要内容,如果未能解决你的问题,请参考以下文章