Mongoose User模型pre('save')钩子无法获取this,bcrypt哈希密码报错
这个Error: data and salt arguments required报错我之前也踩过坑,核心问题出在你用了箭头函数定义pre('save')钩子!
箭头函数不会绑定自己的this,它会继承外层作用域的this,而Mongoose的钩子函数必须用普通函数,才能让this指向当前的文档实例。你代码里的const user = this;实际上拿到的不是用户文档对象,而是undefined,所以bcrypt调用时user.password是空值,直接触发了这个错误。
修复步骤:
把钩子函数改成普通函数
修改你的User模型代码,将箭头函数替换为普通函数,这样this就能正确指向当前的用户文档了:const bcrypt = require('bcrypt'); UserSchema.pre('save', function(next) { const user = this; // 额外优化:只有密码被修改时才执行哈希,避免重复哈希(比如更新邮箱时) if (!user.isModified('password')) { return next(); } bcrypt.hash(user.password, 10, (err, hash) => { if (err) { return next(err); } user.password = hash; next(); }); }); const Users = mongoose.model('Users', UserSchema); module.exports = Users;额外检查点
- 确认创建用户时
req.body.password确实有值:可以在路由里加个日志排查,避免前端传参或中间件把密码清空了:console.log('提交的密码:', req.body.password); // 输出看看是否存在有效密码 const newUser = { username: req.body.username, email: req.body.email, password: req.body.password }; Users.create(newUser, (err) => { if (err) throw err; res.status(201).send('User created'); }); - 你的MongoDB连接代码用了
useMongoClient: true,这是Mongoose 4.x的写法,如果是5.x及以上版本,建议改成兼容新驱动的写法,避免其他潜在问题:mongoose.connect('mongodb://localhost/gederson', { useNewUrlParser: true, useUnifiedTopology: true });
- 确认创建用户时
你遇到的报错信息:
events.js:183 throw er; // Unhandled 'error' event
^
Error: data and salt arguments required
at /home/gedersonchiquesi/ProjetosDev/wos/node_modules/bcrypt/bcrypt.js:114:16
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
[nodemon] app crashed - waiting for file changes before starting...
内容的提问来源于stack exchange,提问作者Gederson Chiquesi

