bcrypt compare/compareSync对比相同字符串始终返回false问题
bcrypt的compare/compareSync始终返回false,明明字符串完全一致
我遇到了bcrypt的compare和compareSync方法一直返回false的问题,哪怕要对比的字符串内容完全一致。我已经用console.log验证过两个字符串相同,也排除了重复哈希的情况,试过网上同类问题的解决方案,但问题还是没解决。
相关代码
model.js
import mongoose from "mongoose"; import bcrypt from "bcryptjs"; const ResetTokenSchema = new mongoose.Schema({ owner: { type: mongoose.Schema.Types.ObjectId, ref: "Doctor", required: true, }, token: { type: String, required: true, }, createdAt: { type: Date, expires: 3600, // 1小时后过期 default: Date.now(), }, }); // 存储前哈希token ResetTokenSchema.pre("save", async function (next) { if (this.isModified("token")) { const encryptedToken = await bcrypt.hash(this.token, 8); this.token = encryptedToken; console.log("加密后的token:" + this.token) } next(); }); ResetTokenSchema.methods.compareToken = async function (encryptedToken) { const result = await bcrypt.compare(encryptedToken, this.token); console.log("数据库中的token:", this.token) console.log("传入的待验证token:", encryptedToken) console.log("对比结果:", result) return result; }; export default mongoose.model("ResetToken", ResetTokenSchema);
控制台输出

问题排查与解决
核心问题分析
从代码和控制台输出来看,最可能的原因有两个:
- 双重哈希导致不匹配:如果在创建
ResetToken文档时,你提前对token做了哈希,然后pre-save钩子又再次哈希了一次,数据库里存储的就是「哈希的哈希」,这时候用明文去对比自然返回false。 - 参数传入错误:虽然你的
compare调用参数顺序(明文在前,哈希值在后)是对的,但要确认传入compareToken的参数确实是明文token,而不是已经哈希过的值。
具体解决步骤
- 创建文档时传入明文token:生成ResetToken的代码里,直接传原始明文token即可,不要提前调用bcrypt.hash,pre-save钩子会自动处理哈希逻辑。
- 修正createdAt默认值写法:
default: Date.now()会在Schema定义时就执行,导致所有文档的过期时间完全相同,改成default: Date.now(去掉括号,传入函数引用),这样每次创建文档时才会生成当前时间。 - 检查钩子触发逻辑:如果更新文档时不需要修改token,确保不会误触发
isModified("token"),避免重复哈希。
内容的提问来源于stack exchange,提问作者glacto5
相关产品推荐
相关产品推荐

