【发布时间】:2022-04-26 12:47:00
【问题描述】:
我是一个完全的编码初学者,目前正在学习 NodeJs,而且我已经被这种情况困住了好几天了。 我正在尝试将我的 mongodb 中的散列密码与通过邮递员输入的用户进行比较。 我正在使用 bcrypt 将散列密码与原始字符串进行比较,但我得到了错误的陈述。 非常感谢任何帮助
这是猫鼬模型的Schema,
const usersSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
email: {
type: String,
unique: true,
required: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) throw new Error("Invalid email");
},
},
password: {
type: String,
required: true,
trim: true,
minLength: 7,
validate(value) {
if (value.toLowerCase().includes("password")) {
throw new Error("Password should not consist of string 'password'.");
}
},
},
})
在这里我在保存到数据库之前对密码进行哈希处理;
usersSchema.pre("save", async function (next) {
const user = this;
const saltRounds = 8;
if (user.isModified("password")) {
user.password = await bcrypt.hash(user.password, saltRounds);
}
next();
});
下面是登录路径;
router.post("/users/login", async (req, res) => {
try {
const user = await Users.findByCredentials(
req.body.email,
req.body.password
);
res.send(user);
} catch (error) {
res.status(400).send(error);
}
});
下面是我尝试比较密码的地方,请帮助我找出错误的原因。
usersSchema.statics.findByCredentials = async (email, password) => {
const user = await Users.findOne({ email: email });
if (!user) {
throw new Error("Unable to log in!");
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw new Error("Unable to login");
}
return user;
};
【问题讨论】:
-
我想知道,你如何保存和更新用户。您的“保存”挂钩存在一个问题。 “保存”钩子不会在更新和 findOneAndUpdate 时执行。因此,当密码更新时,它不会被散列。您应该使用其他钩子,例如
updateOne或findOneAndUpdate。 -
我已经尝试将钩子 findOne 更改为 findOneAndUpdate 但结果仍然是错误的。
-
而且似乎 bcrypt 每次都产生不同的哈希值,即使我给它提供相同的字符串也是如此。所以这永远不会匹配。
-
在比较之前只需 console.log
password和user.password,并确保值符合您的预期。这样你可以缩小问题的范围 -
是的,这些值是不同的,不明白为什么?
console.log(user.password)// $2a$08$hnfxw2ws.jznauegxrrty.mlrfcwjkatwb/a580lbeu51gvzbzvyiconsole.log(await bcrypt.hash(password, 8))// $2a$08$7fd4NhW6lV2AbsmCf7N20OyvguGZslFukafqS6mk2QYMeVYtUHpan>Wj