NestJs搭配SQL Server时bcrypt.compare始终返回false如何解决
bcrypt.compare 始终返回 false 解决建议
问题根因排查及对应解决方法
1. 数据库密码字段长度不足
bcrypt 生成的标准哈希值固定为 60 位,若数据库 users 表的 password 字段长度设置小于 60,哈希值会被截断导致对比失败。
- 先登录 MSSQL 数据库查看
password字段实际存储值的长度,若不足 60 位即可确认是该问题 - 修改实体字段定义,指定最小长度:
@Column({ nullable: true, length: 60 }) password: string;
- 同步更新数据库表结构,将
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
相关产品推荐
相关产品推荐

