我正在调用
bcrypt.checkpw
检查未加密的密码与存储在凭证数据库中的哈希密码是否匹配,但收到
类型错误:在检查之前必须对 Unicode 对象进行编码
我该如何解决这个问题?有什么建议吗?
我安装了
python 2.7.6
,并且bcrypt 3.1.1
我有以下代码:
def check_password(password, hashed_password)
if not bcrypt.checkpw(password, hashed_password):
raise InvalidCredentials("403 Forbidden")
else:
return true
并收到以下错误:
文件“/home/qt/virtualenv/lib/python2.7/site-packages/bcrypt/init.py”,第 100 行,在 checkpw
raise TypeError(“在检查之前必须对 Unicoed 对象进行编码”)
类型错误:在检查之前必须对 Unicode 对象进行编码
我调查了
bcrypt/__init__.py
,但我不知道为什么
def checkpw(password, hashed_password):
if (isinstance(password, six.text_type) or
isinstance(hashed_password, six.text_type)):
raise TypeError("Unicode-objects must be encoded before checking")
我假设您使用 Python 3。使用 Python 3,字符串默认为 unicode 字符串。
如果您使用 unicode 值调用
bcrypt.checkpw()
函数:
import bcrypt
password = "seCr3t" # unicode string
hashed_password = "hashed_seCr3t" # unicode string
bcrypt.checkpw(password, hashed_password)
你会得到这个异常
Traceback (most recent call last):
...
TypeError: Unicode-objects must be encoded before checking
原因很简单:加密函数仅适用于字节字符串(或实际上是数组)。
您 password 和 hashed_password 必须都是字节字符串。
如果您使用
bcrypt.hashpw()
函数,您的 hashed_password 必须是字节字符串,我认为问题在于 password 值。这个password必须来自类似的HTML形式。要使用 bcrypt.checkpw()
函数,您必须首先使用与使用 bcrypt.hashpw()
函数加密 password相同的编码对字符串值进行编码。通常,我们选择“utf8”编码。
例如(Python 2 和 3):
import bcrypt
# at creation first:
password = u"seCr3t"
hashed_password = bcrypt.hashpw(password.encode('utf8'), bcrypt.gensalt())
# first attempt:
password = u"seCrEt"
bcrypt.checkpw(password.encode('utf8'), hashed_password)
# -> False
# second attempt:
password = u"seCr3t"
bcrypt.checkpw(password.encode('utf8'), hashed_password)
# -> True
你可以这样做
bcrypt.checkpw(password.encode('utf-8'), hashed_password)
简单易行
我用类似的东西
class User(Base):
__tablename__ = "user"
id = Column(BigInteger, primary_key=True, autoincrement=True)
login = Column(String, nullable=False, unique=True)
password = Column(String, nullable=False)
@staticmethod
def make_password_hash(password):
hash = bcrypt.hashpw(password=password.encode('utf-8'), salt=bcrypt.gensalt())
return hash.decode('utf-8')
def is_password_valid(self, password):
return bcrypt.checkpw(password.encode('utf-8'), self.password.encode('utf-8'))
使用它,例如并查看代码下面的注释:
import bcrypt
def comparacaoSenha(passw, hash):
if bcrypt.checkpw(passw, hash):
print("It Matches!")
else:
print("It Does not Match")
password = "super secret password".encode('utf-8')
password2 = "another password".encode('utf-8')
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
heashed2 = bcrypt.hashpw(password2, bcrypt.gensalt())
print("Teste 1: ")
print("-----------------------------")
print("PASSWORD: ", password)
print("HASHED PW: ", hashed)
comparacaoSenha(password, hashed)
print("-----------------------------")
print("Teste 2: ")
print("-----------------------------")
print("PASSWORD: ", password2)
print("HASHED PW: ", heashed2)
comparacaoSenha(password2, heashed2)
print("-----------------------------")
# Things to remember:
# always use the encode('utf-8') or put a prefix 'b'' just before the strings
# EX: newPass = b"OTHER PASSWORD" // or newPass="OTHER PASSWORD".encode('utf-8')
#
我遇到了同样的错误,这是解决方案 在检查之前必须先编码后解码 hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
如果用户和bcrypt.checkpw(password.encode('utf8'), user.password.encode('utf-8')):