Django check_password() 总是返回 False

Django check_password() always returning False

我有一个与 NodeJs 应用程序一起使用的现有数据库,现在相同的数据库将用于使用 Django 构建的新应用程序。 我有一个 user_account table,它存储用户登录凭据,并且用于密码加密 bcrypt 模块已被使用。密码存储在字段 user_password

我已经扩展了 Django Users 模型并覆盖了它的 authencticate 方法,它工作正常。 对于密码验证,我使用的是 bcrypt 方法 bcrypt.checkpw(password, hashed),它也工作正常。

问题: 我想使用 django user.check_password(password) 而不是 bcrypt.checkpw(password, hashed)。因为它会省去在密码匹配之前生成盐和编码的痛苦,而且最重要的是它是一个用于唯一目的的内置方法。

import bcrypt
from django.contrib.auth.hashers import check_password

#password = plain text password entered by user at login
#hashedPassword = Password stored in db (fieldName: user_password)
check_password(password, hashedPassword) #It returns False

user.check_password(password) # It also returns False

#for same password
bcrypt.checkpw(password, hashedPassword) # returns True

#hashedPassword format b$NNVaNL2Zla0E/WwC6Mkjjer6Qh3zIBCN6kMl9qxLE/xxyt4NAgXMq

我正在使用 Django 2.1 并且 Python3.6

我已经检查过相关问题,但所有问题都与表单有关,我没有使用任何 django 表单。

我的settings.py哈希器如下

PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.Argon2PasswordHasher',
]

输入法是一个简单的django模板

<div class='col-md-12'>
  <form action='/auth/login' method='post'>
    {% csrf_token %}
    <div class='form-group row'>
      <label for='email'>Email</label>
      <input type='email' class='form-control' id='email' name='username'>
    </div>
    <div class='form-group row'>
      <label for='password'>Password</label>
      <input type='password' class='form-control' id='password' name='password'>
    </div>
    <div class='form-group row'>
      <button class='btn btn-outline-secondary' type='submit'>Log in</button>
    </div>
  </form>
</div>

Django 不存储原始哈希值,它们以算法为前缀(参见 documentation)。

没有前缀,Django 将无法识别正确的哈希器。如果您查看 source of check_password,您会看到它 returns False 如果它无法识别密码哈希器。

最干净的解决方案可能是 a custom authentication backend 直接使用 bcrypt.checkpw

我解决了这个问题:

from django.contrib.auth.hashers import make_password
password = make_password('yourpassword')

check_password

has_usable_password

returns 现在正确的值