使用SQLAlchemy存储密码至PostgreSQL时登录遇Invalid salt错误
解决bcrypt验证密码时的"Invalid salt"错误
问题原因
你的代码存在类型不匹配问题:
encode_password返回bytes类型的哈希值,但User模型的password字段定义为String类型。存储到PostgreSQL时,bytes会被自动转换为带b''前缀的字符串(比如原始哈希b'$2b$12...'会变成"b'$2b$12...'")。- 验证时调用
hashed_password.encode("utf-8"),实际传入bcrypt的是b"b'$2b$12...'",这种格式不符合bcrypt的哈希规范,导致无法识别盐,抛出Invalid salt错误。
解决方案
有两种可行的修复方式,选其一即可:
方式1:修改编码函数,返回字符串类型
将哈希后的bytes直接转成utf-8字符串,确保存储和读取的格式一致:
import bcrypt def encode_password(password: str) -> str: """哈希密码""" return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") def verify_password(password: str, hashed_password: str): """验证密码""" return bcrypt.checkpw(password.encode("utf-8"), hashed_password.encode("utf-8"))
方式2:修改User模型的密码字段为Binary类型
让数据库直接存储字节数据,避免类型转换带来的问题:
from sqlalchemy import Column, Integer, String, Binary from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True) mobile = Column(String, unique=True, nullable=False) email = Column(String, unique=True, nullable=False) password = Column(Binary, nullable=False)
同时调整验证函数,直接使用原始bytes进行验证:
def verify_password(password: str, hashed_password: bytes): """验证密码""" return bcrypt.checkpw(password.encode("utf-8"), hashed_password)
注意事项
如果数据库中已经存储了错误格式的密码(带b''前缀的字符串),需要重新生成这些用户的哈希密码,否则验证仍会失败。
内容的提问来源于stack exchange,提问作者AliAryaie
相关产品推荐
相关产品推荐

