You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:54:26