我正在使用 Mongoose 驱动程序在 NodeJS 中制作 REST API。我想在保存密码之前对其进行哈希处理。同样,我使用 Mongoose Schema,为我的用户模型创建了 userSchema。对于散列,我使用了以下函数。
userSchema.pre('save', async (next) => {
const user = this;
console.log(user);
console.log(user.isModified);
console.log(user.isModified());
console.log(user.isModified('password'));
if (!user.isModified('password')) return next();
console.log('just before saving...');
user.password = await bcrypt.hash(user.password, 8);
console.log('just before saving...');
next();
});
但是在创建用户或修改用户时,我收到错误 500,并且返回了 {}。我的路由器如下。
router.post('/users', async (req, res) => {
const user = User(req.body);
try {
await user.save();
res.status(201).send(user);
} catch (e) {
res.status(400).send(e);
}
});
router.patch('/users/:id', async (req, res) => {
const updateProperties = Object.keys(req.body);
const allowedUpdateProperties = [
'name', 'age', 'email', 'password'
];
const isValid = updateProperties.every((property) => allowedUpdateProperties.includes(property));
if (!isValid) {
return res.status(400).send({error: "Invalid properties to update."})
}
const _id = req.params.id;
try {
const user = await User.findById(req.params.id);
updateProperties.forEach((property) => user[property] = req.body[property]);
await user.save();
if (!user) {
return res.status(404).send();
}
res.status(200).send(user);
} catch (e) {
res.status(400).send(e);
}
});
以下是我的控制台输出。
Server running on port 3000
{}
undefined
注释掉 userSchema.pre('save', ...) 后,一切都按预期工作。请你帮我找出哪里错了。
对 mongoose 使用函数定义代替箭头函数
pre
节省中间件:
userSchema.pre('save', async function(next) { // this line
const user = this;
console.log(user);
console.log(user.isModified);
console.log(user.isModified());
console.log(user.isModified('password'));
if (!user.isModified('password')) return next();
console.log('just before saving...');
user.password = await bcrypt.hash(user.password, 8);
console.log('just before saving...');
next();
});
更新:
区别在于
this
上下文,如果您在这一行中使用arrow
函数const user = this;
,这现在就是您当前的文件(我猜是架构文件)。
当您使用
function
关键字时,this
上下文将属于调用者对象(用户实例)。
或使用
.bind(this)
作为中间件