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

NestJs搭配SQL Server时bcrypt.compare始终返回false如何解决

bcrypt.compare 始终返回 false 解决建议

问题根因排查及对应解决方法

  • 1. 数据库密码字段长度不足

bcrypt 生成的标准哈希值固定为 60 位,若数据库 users 表的 password 字段长度设置小于 60,哈希值会被截断导致对比失败。

  1. 先登录 MSSQL 数据库查看 password 字段实际存储值的长度,若不足 60 位即可确认是该问题
  2. 修改实体字段定义,指定最小长度:
@Column({ nullable: true, length: 60 })
password: string;
  1. 同步更新数据库表结构,将 password 字段长度调整为至少 60 位,重新创建测试用户验证即可。
  • 2. 字符串存在不可见空白字符

用户输入的密码、数据库返回的哈希值都有可能附带首尾空白字符,导致对比失败。修改 validatePassword 方法,对比前先做去空白处理:

async validatePassword(password: string): Promise<boolean> {
  const inputPwd = password.trim();
  const storedHash = this.password?.trim() || '';
  const isValidUser = await bcrypt.compare(inputPwd, storedHash);
  return isValidUser;
}
  • 3. 实体构造逻辑异常

你当前自定义了带参构造函数,TypeORM 从数据库加载实体时默认调用无参构造,若业务代码中手动实例化 UserEntity 时错误传入明文密码而非数据库存储的哈希值,会导致对比失败。可临时移除自定义构造函数,使用 TypeORM 默认的实体实例化逻辑测试验证。

  • 4. 密码被重复哈希

检查创建用户的业务逻辑,若在调用 save 方法前已经手动对密码做了一次哈希,加上 @BeforeInsert 内置的哈希逻辑,相当于对明文密码做了两次哈希,自然无法和登录时的明文对比。移除业务代码中的手动哈希逻辑,仅保留 @BeforeInsert 中的哈希逻辑即可。

内容的提问来源于stack exchange,提问作者Ricardo Lamar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:15:05