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

Node.js Express中使用await后密码Hashing不生效问题咨询

问题根因

你当前调用的是bcrypt的回调风格异步接口,JavaScript不会等待回调函数执行完成,就会直接执行后续的数据库更新、返回响应的逻辑,此时password还是原始未哈希的值,所以入库的密码没有被处理。你遇到的res.json返回了哈希后密码属于偶发情况,只是哈希操作碰巧在响应返回前执行完成,不属于稳定可预期的行为。

解决方案

方案1:改用bcrypt的async/await风格API(推荐,和你现有async路由写法适配)

bcrypt原生支持Promise调用,直接用await等待哈希完成再执行后续逻辑即可:

router.put('/:id', async (req, res, next) => {
  try {
    let { mail, password } = req.body;
    // 直接用await调用genSalt和hash,等待异步操作完成
    const salt = await bcrypt.genSalt(saltRounds);
    const hash = await bcrypt.hash(password, salt);
    password = hash;

    const newUser = { mail, password };
    await User.findByIdAndUpdate(req.params.id, newUser);
    res.json({ mensaje: `Updated Password ${password}` });
  } catch (err) {
    // 统一捕获异步错误
    next(err);
  }
});

方案2:把后续逻辑移入回调函数(不推荐,容易形成回调地狱)

如果你要继续用回调写法,需要把数据库更新、返回响应的逻辑都放到hash的回调内部,保证哈希完成后再执行后续操作:

router.put('/:id', async (req, res, next) => {
  let { mail, password } = req.body;

  bcrypt.genSalt(saltRounds, function (err, salt) {
    if (err) return next(err);

    bcrypt.hash(password, salt, async function (err, hash) {
      if (err) return next(err);
      password = hash;
      // 所有用到哈希后password的逻辑都要放在回调内部
      const newUser = { mail, password };
      await User.findByIdAndUpdate(req.params.id, newUser);
      res.json({ mensaje: `Updated Password ${password}` });
    });
  });
});

额外建议

  • 哈希密码的逻辑建议封装到用户模型的pre('save')钩子里面,避免每次写更新/注册接口都要手动处理哈希,减少出错概率
  • 响应返回结果里不要带出哈希后的密码,避免泄露敏感信息

内容的提问来源于stack exchange,提问作者Kempis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:54:03