Django模型中的密码字段

Rub*_*nes 25 django django-models django-admin

我正在尝试创建一个模型,我可以在其中存储其他应用程序的用户名和密码.如何在Django中设置密码字段,使其在管理员中不是纯文本?提前致谢.

Man*_*dan 27

正如@mlissner 所说,这个auth.User模型是个好看的地方.如果您检查源代码,您将看到该password字段是a CharField.

password = models.CharField(_('password'), max_length=128, help_text=_("Use 
'[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
Run Code Online (Sandbox Code Playgroud)

User模型还有一种set_password方法.

def set_password(self, raw_password):
    import random
    algo = 'sha1'
    salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
    hsh = get_hexdigest(algo, salt, raw_password)
    self.password = '%s$%s$%s' % (algo, salt, hsh)
Run Code Online (Sandbox Code Playgroud)

您可以从此方法中获取有关创建密码并保存密码的一些线索.

  • 正如Marc在下面回答的那样,你做不到.但是您可以使用相同的algo和salt来散列用户提供的密码,并检查该值是否等于您在数据库中存储的值. (4认同)
  • 自从发布此答案以来,Django 已经更改了 *lots* — 以允许覆盖和更改 User 模型 — 但要点仍然是正确的。新 `AbstractBaseUser` 的设置和密码检查的繁重部分位于 [`django.contrib.auth.hashers`](https://github.com/django/django/blob/master/django/contrib /auth/hashers.py)。同样,虽然这个答案的散文通常是正确的,但代码已经过时了。答案可以通过一些仔细的重写来完成。 (3认同)

mli*_*ner 5

你最好的选择(我知道)是深入研究 django 代码中的代码,看看它是如何完成的。我记得,它们生成一个加盐哈希,以便纯文本值永远不会存储在任何地方,而是哈希和盐。

如果你进入 django 安装,并查找像 hash 和 salt 这样的词,你应该很快就能找到它。很抱歉回答含糊不清,但也许它会让您走上正确的道路。


小智 5

我不认为您将能够解密以与普通django用户密码类似的方式存储的加密密码.部分安全性是它们不可拆卸.


小智 5

不幸的是,这个问题没有一个简单的答案,因为它取决于您尝试对其进行身份验证的应用程序,还取决于您希望密码字段的安全性。

如果您的 Django 应用程序将使用密码来验证另一个需要发送明文密码的应用程序,那么您的选择是:

  • 将密码以纯文本形式存储在 Django 模型中(您的问题暗示您不想这样做)
  • 在用户为其他应用程序解锁存储的密码之前,从用户那里获取主密码
  • 混淆模型中的密码,以便任何具有原始数据存储权限的人都可以访问它,但对普通观众来说并不明显

如果您使用的是 Django 的内置用户模型,则可以使用 Django 用户密码作为主密码。这意味着您需要将该主密码保存在内存中,这可能会给您带来一些操作困难,例如重新启动服务器或运行负载平衡的冗余服务器。

存储密码的替代方法

幸运的是,许多现代应用程序使用基于密钥而不是基于密码的访问令牌系统以另一种方式支持这一点。引导用户完成在两个应用程序之间建立链接的过程,并且在幕后,应用程序生成密钥以永久或具有定义的到期日期来相互验证。

例如,Facebook 支持这种模型,并且他们有大量关于其工作原理的文档:

Facebook 开发人员:访问令牌和类型

一旦您设法使用 [OAuth 2.0](http://tools.ietf.org/html/draft-ietf-oauth-v2-12) 链接到 Facebook,您可能会发现使用它添加指向其他应用程序的链接更容易相同的协议。