【问题标题】:Save a field as hash and compare it in django将字段保存为哈希并在 django 中进行比较
【发布时间】:2021-08-28 00:14:13
【问题描述】:

我创建了自己的用户模型:

class CustomUser(AbstractBaseUser,PermissionsMixin):
    phone_number = models.CharField(verbose_name="Mobile Number", max_length=11, unique=True, blank=False, null=False)
    security_code = models.IntegerField(verbose_name="Security Code",default=create_security_code)
    security_code_creation = models.DateTimeField(auto_now=True)

用户可以使用密码或安全码登录。

我希望它是这样的:

如果用户想使用安全代码登录,我将在我的视图中创建一个随机安全代码。将其发短信给他们,并将安全代码的散列版本保存在我的数据库中。用户从他们收到的文本中输入数字,我将用户输入的哈希版本与我在数据库中的内容进行比较。很像密码。

但我不想将安全代码作为纯文本存储在我的数据库中。我想像密码(散列)一样存储它。

我找到了

from django.contrib.auth.hashers import make_password

我可以使用它来创建安全代码的散列版本。

我的问题是我应该编写一个单独的身份验证后端还是简单地编写/使用像 check_password 这样植入 AbstractBaseUser 的函数?

【问题讨论】:

  • “如果需要,我会给他们发送安全代码”意味着安全代码必须以您可以阅读的方式存储,这样它就不会被散列?
  • 我将在我的视图中创建一个随机安全码。发短信给用户。将其保存为散列。它会在一段时间后过期(因此 security_code_creation )
  • 为什么要有代码和密码?如果他们必须要求一个代码,为什么不要求一个新密码呢?
  • 这在我的国家很普遍。有时用户甚至不会设置密码,而只使用这种方式登录,因为它就像一次性密码一样。
  • 覆盖check_password 是一个很好的解决方案,自定义后端通常用于从其他来源进行身份验证

标签: python django


【解决方案1】:

在您的自定义用户类中覆盖 check_password 可以像这样工作。

您在登录时提供密码或代码,该方法首先检查该值是否与密码匹配,如果不匹配则检查该值是否与安全代码匹配

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

class CustomUser(AbstractBaseUser, PermissionsMixin):
    ...
    security_code = models.CharField(verbose_name="Security Code",max_length=128)
    ...
    def set_security_code(self, code):
        self.security_code = make_password(code)
        self.security_code_creation = now()

    def check_password(self, raw_password):
        password_matched = super().check_password(raw_password)
        if not password_matched and self.security_code_creation > now() - timedelta(days=1):
            return check_password(raw_password, self.security_code)
        return False

【讨论】:

  • 只有一个问题。 security_code 字段应该如何更改以便它可以存储散列值?我知道密码使用最大长度为 128 的字符字段。我应该将我的 security_code 字段更改为该字段吗?
  • 是的,现有的密码字段长度足以保存生成的哈希
  • 感谢您的回答,我提交了对该字段的回答的编辑。
  • 不用担心,将 security_code 的检查移至它自己的方法可能是进一步的改进,以便它可以单独运行和测试
猜你喜欢
  • 2012-08-18
  • 2013-12-21
  • 1970-01-01
  • 2012-08-14
  • 2014-10-19
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
相关资源
最近更新 更多