You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:05:21