使用Bcrypt重置密码时无法保存更新后的密码问题求助
密码重置流程中Bcrypt哈希密码无法更新的问题解决
问题描述
开发密码重置流程时,除了Bcrypt密码哈希后的更新操作外,其余环节(生成重置链接、保存resetPasswordToken/resetPasswordExpires、token有效性校验、重置token和过期时间)均正常执行,但user.password = hashedPassword无法将新哈希密码保存到数据库中。
参考的Bcrypt文档语法
const hash = bcrypt.hashSync(myPlaintextPassword, saltRounds); // Store hash in your password DB.
实现函数
module.exports.submitNewPassword = async (req, res) => { // console.log(req.body.password, req.params, req.headers.referer ); const slidedHeaderToken = req.headers.referer.slice(-40); const user = await User.findOne({ resetPasswordToken: slidedHeaderToken, resetPasswordExpires: { $gt: Date.now() } }); console.log("submitNewPassword user ", user); if (!user) { console.log("user not found"); req.flash('error', "Password reset token is invalid or has expired"); res.render('users/reset') } else { // hash the new password const hashedPassword = await bcrypt.hash(req.body.password, 12); // update the user's password user.password = hashedPassword; user.resetPasswordToken = undefined; user.resetPasswordExpires = undefined; await user.save(); res.redirect('/users/login'); } }
可能的原因及解决方法
检查Mongoose Schema的password字段配置
如果User Schema中password字段设置了immutable: true,或者未正确配置可修改属性,会导致无法更新。确保Schema定义正确:const userSchema = new mongoose.Schema({ password: { type: String, required: true, // 不要设置immutable: true,除非业务不允许修改密码 }, resetPasswordToken: String, resetPasswordExpires: Date });改用
findOneAndUpdate直接更新数据库
直接修改文档属性后调用save()可能受中间件或验证逻辑干扰,改用findOneAndUpdate可以绕过部分问题:// 替换else块内的代码 const hashedPassword = await bcrypt.hash(req.body.password, 12); await User.findOneAndUpdate( { _id: user._id }, { password: hashedPassword, resetPasswordToken: undefined, resetPasswordExpires: undefined } ); res.redirect('/users/login');添加错误捕获逻辑
bcrypt.hash和user.save都是异步操作,若未捕获异常,出错时会静默终止流程。添加try/catch块排查问题:else { try { const hashedPassword = await bcrypt.hash(req.body.password, 12); user.password = hashedPassword; user.resetPasswordToken = undefined; user.resetPasswordExpires = undefined; const savedUser = await user.save(); console.log("更新后的用户密码:", savedUser.password); // 验证是否更新成功 res.redirect('/users/login'); } catch (err) { console.error("密码重置失败原因:", err); req.flash('error', "密码重置失败,请稍后重试"); res.render('users/reset'); } }验证
user.save()的执行结果
调用save()后打印返回的文档,确认password字段是否已更新。如果是验证错误,根据错误信息调整Schema或输入参数。
内容的提问来源于stack exchange,提问作者econobro
相关产品推荐
相关产品推荐

