我有用户模型的以下代码
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: {
type: String,
required: true,
trim: true,
minlength: 3,
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
})
然后为了哈希密码我有这个代码
UserSchema.pre('save', function (next) {
if (this.isModified('password')){
bcrypt.genSalt(10, (err, salt)=>{
bcrypt.hash(this.password, salt, (err, hash)=>{
this.password = hash;
next();
})
});
}
next();
})
然后,为了检查来自用户的输入值的哈希,我有以下代码
userSchema.statics.comparePassword = function(password){
let user = this;
return bcrypt.compareAsync(password, user.password)
}
因此,当涉及到所有这些代码片段的使用时,我有以下内容
async loginUser(req, res) {
try{
const {email, password} = req.body
const user = await User.findOne({
email: req.body.email
})
if(!user){
return res.status(403).send({
error: "Incorrect details email"
})
}
const isPassValid = await user.comparePassword(password)
}catch(err){
res.status(403).send({
error: "The bid deal happened"
})
}
}
所以我尝试在谷歌搜索和在这个论坛上找到答案,但一切似乎已经过时或不适合我的情况。这段代码总是发送“出价交易”,我试图从各方调试它,但它仍然不成功。
问题是如何使它工作?这样我就能以正确的方式比较密码
P.S我尝试从compareAsync更改为compareSync,显示无效
您在更改值时加密密码,但在插入新的mongo文档时不加密,您可以使用document.isNew
进行检查。
我已将您的保存方法更新为以下内容。
UsersSchema.pre('save', function (next) {
let user = this;
if (this.isModified('password') || this.isNew) {
bcrypt.genSalt(10, (err, salt) => {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
} else {
next();
}
});
此外,Schema.statics
用于服务static
方法。 this
上下文不会返回用户,因此使this.password
未定义。要使用方法填充模式的实例,必须将它们附加到Schema.methods
对象。
我过去使用过bcrypt.compare
,我不知道bcrypt.compareAsync
是否是一个有效的方法,因为第一个已经是异步的。如果它是异步的,它将不会直接返回一个值。比较需要回调。
UsersSchema.methods.comparePassword = function (password, callback) {
bcrypt.compare(password, this.password, (err, isMatch) => callback(err, isMatch));
};
要比较密码,您可以执行以下操作:
const { email, password } = req.body
User.findOne({
email: email,
}, (err, user) => {
if (err) throw err;
if (user) {
user.comparePassword(password, (err, match) => {
if (match && !err) {
// match
}
});
}
});