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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:20:28