更新用户密码时如何验证旧密码,避免ERR_HTTP_HEADERS_SENT报错
错误原因
- 执行逻辑完全颠倒:未验证旧密码正确性就先执行了密码更新操作,直接将明文新密码写入了数据库,存在严重安全漏洞
- 异步回调执行时序冲突:你使用了回调式写法调用bcrypt的异步方法,代码不会等待旧密码校验完成就直接往下执行新密码哈希逻辑,当旧密码校验失败返回400响应后,后续的哈希逻辑还会尝试再次返回响应,触发ERR_HTTP_HEADERS_SENT报错
- 异常捕获范围无效:回调函数内的异常无法被外层的try/catch捕获,导致异常时会出现重复返回响应的问题
正确实现代码
统一使用async/await写法处理异步逻辑,调整操作顺序为「查询用户→校验旧密码→哈希新密码→更新数据库→返回结果」:
exports.updatePassword = async (req, res) => { try { const { oldPassword, password } = req.body; // 1. 查询目标用户信息 const user = await User.findById(req.params.userId); if (!user) { return res.status(404).send('用户不存在'); } // 2. 校验旧密码是否匹配 const isOldPasswordCorrect = await bcrypt.compare(oldPassword, user.password); if (!isOldPasswordCorrect) { return res.status(400).send('请输入正确的旧密码'); } // 3. 生成新密码哈希值 const salt = await bcrypt.genSalt(12); const hashedNewPassword = await bcrypt.hash(password, salt); // 4. 更新数据库中的用户密码 const updatedUser = await User.findByIdAndUpdate( req.params.userId, { $set: { password: hashedNewPassword } }, { new: true, useFindAndModify: false } ); // 5. 返回更新后的用户信息 return res.json({ user: updatedUser }); } catch (err) { console.log(err); return res.status(400).send('操作出错,请重试'); } };
内容的提问来源于stack exchange,提问作者Babadinho
相关产品推荐
相关产品推荐

