passport-local-mongoose调用setPassword报is not a function错误
报错核心原因
user.setPassword is not a function报错的根源是查询方法使用错误:你调用的User.find()会返回匹配查询条件的文档数组,哪怕根据_id查询只有一条匹配结果,拿到的也是长度为1的数组,数组对象上不存在passport-local-mongoose注入的setPassword实例方法,调用自然报错。
你的User Schema编写、插件注册逻辑没有问题,setPassword方法已经正确挂载到User模型的单个文档实例上。
修复方法
- 单条文档查询不要用
find(),替换为返回单个文档实例的方法:根据_id查询优先用User.findById(),或者用User.findOne(),拿到的单个用户实例才能正常调用setPassword方法。 - 补全原代码缺失的错误处理逻辑,避免密码未实际保存就提前返回成功响应的问题。
修正后的密码修改逻辑代码:
const change_password = (req, res) => { const password = req.body.password // 用findById直接根据用户id查询单个实例 User.findById(req.user._id) .then((user) => { if (!user) { return res.status(404).json({ msg: '用户不存在' }) } user.setPassword(password, function(err) { if (err) { return res.status(500).json({ msg: '密码加密失败', error: err.message }) } user.save(function(saveErr) { if (saveErr) { return res.status(500).json({ msg: '密码保存失败', error: saveErr.message }) } console.log('user password changed') res.status(200).json({ msg: 'The password has been changed' }) }) }) }) .catch(e => { console.log(e); res.status(500).json({ msg: '服务异常', error: e.message }) }) }
如果误写
find()又不想改查询方法,也可以在拿到结果后取数组第一项user[0].setPassword()调用,但这种写法语义差,还需要额外判断数组长度,不推荐使用。
内容的提问来源于stack exchange,提问作者Kotai
相关产品推荐
相关产品推荐

