Django中用bcrypt哈希验证密码遇TypeError,求字段类型及解决方案
解决Django中bcrypt报错TypeError: Strings must be encoded before checking的问题
问题根源
你当前用models.CharField存储bcrypt哈希值,但bcrypt生成的哈希是bytes类型,存入CharField时会被自动转成字符串(比如b'$2b$14...'会变成字符串 "b'$2b$14...'")。验证密码时,你传入的encodedPass是bytes类型,而从数据库取出的密码是字符串类型,bcrypt.checkpw要求两个参数都必须是bytes,因此触发错误。
正确的数据库字段类型
把密码字段改成models.BinaryField,它专门用于存储二进制数据,完美适配bcrypt返回的bytes哈希:
password = models.BinaryField(null=True, blank=True)
不需要设置max_length,BinaryField会自动处理存储长度。
代码调整说明
- 设置密码的代码无需修改:
bcrypt.hashpw返回的bytes可以直接存入BinaryField。 - 验证密码的代码也无需修改:从BinaryField取出的
instance.userprofile.password是bytes类型,和encodedPass(bytes)匹配,bcrypt.checkpw能正常执行。
额外注意
- 修改字段后,执行Django数据库迁移命令:
python manage.py makemigrations python manage.py migrate
- 若之前已用CharField存储了数据,需要手动将字符串格式的bytes(比如
"b'$2b$14...'")转换为真实的bytes类型后再存入BinaryField,否则旧数据无法正常验证。
内容的提问来源于stack exchange,提问作者Kyle Andrew
相关产品推荐
相关产品推荐

