NodeJS中Bcrypt报错Error: Illegal callback: string的解决求助
修改密码API错误解决方案
错误根源
bcrypt.compare的参数传递错误:该方法的正确参数格式为(明文密码, 已加密密码, 回调函数),你额外传入了salt参数,导致方法把字符串类型的salt误认为是回调函数,直接触发Illegal callback: string错误。
其他隐藏问题
User.findByPk是异步方法,直接赋值得到的是Promise对象,不是实际用户实例,后续if (!user)判断永远不成立,且user.password会返回undefined。- 响应语句
res.status(200).send放在异步回调外部,会导致不管密码验证是否成功,都会提前返回成功响应,异步逻辑还未执行完就结束请求。 user.set方法中的where参数多余,操作已查询到的用户实例时无需指定查询条件。- 异步回调内的错误无法被外层
try/catch捕获,因为回调函数属于独立执行上下文。
修复后的完整代码
exports.changePassword = async (req, res) => { try { // 异步获取实际用户实例 const user = await User.findByPk(req.params.user_id); const body = req.body; if (!user) { return res.status(400).send("无效的用户ID"); } // 调用bcrypt.compare时移除多余的salt参数,改用async/await简化逻辑 const isMatch = await bcrypt.compare(body.password, user.password); if (!isMatch) { return res.status(400).send("密码不匹配!"); } // 生成新密码哈希值 const salt = bcrypt.genSaltSync(10); const newPassword = bcrypt.hashSync(body.newPassword, salt); // 更新用户属性,无需where参数 user.set({ password: newPassword, updated_at: now() }); await user.save(); // 操作成功后再返回响应 res.status(200).send("密码修改成功!"); } catch (error) { res.status(500).send("发生错误"); console.log(error); } };
关键修改说明
- 将控制器函数改为
async,用await获取User.findByPk的结果,确保拿到实际用户实例。 - 移除
bcrypt.compare的salt参数,改用async/await替代回调写法,让错误能被外层try/catch捕获。 - 将响应语句移到密码验证通过、用户保存完成之后,保证只有操作成功才返回成功信息。
- 删除
user.set中的where选项,直接修改已查询到的用户实例属性即可。
内容的提问来源于stack exchange,提问作者KAITO_NGUYEN 2KXXX
相关产品推荐
相关产品推荐

