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

使用NodeJS比对MySQL存储的哈希密码时无法正常登录求助

以下是某系统登录功能的代码片段,该功能要求用户输入邮箱和密码完成系统登录,即便输入的账号信息正确,代码也始终报错“邮箱或密码不正确”。我使用的技术栈为NodeJS和MySQL数据库,恳请帮忙排查问题!

问题排查

核心错误点

  • 执行顺序错误:在判断数据库查询错误、判断查询结果是否存在之前,就直接访问results[0].password,如果邮箱不存在/数据库查询报错,results[0]为undefined,读取password属性直接抛出异常,后续校验逻辑无法正常执行
  • 空结果判断逻辑错误:MySQL查询无匹配数据时返回空数组而非null,空数组的布尔值为true,!results判断永远为假,无法命中无匹配用户的分支
  • 冗余查询:同一邮箱重复执行两次查询,完全可以复用第一次的查询结果
  • 变量未声明:sess、patientSess未用const/let声明,属于隐式全局变量,可能引发不可预知的作用域问题

修复后代码

exports.afterLogin = async (req, res) => {
  try {
    const { email, password } = req.body;

    db.query('Select * FROM patient WHERE email= ?', [email], async (error, results) => {
      // 先判断查询错误
      if (error) {
        console.log(error);
        return res.status(500).render('patientLogin', {
          message: '服务器内部错误',
          messageClass: 'alert-danger'
        });
      }
      // 再判断是否存在匹配用户
      if (!results.length) {
        return res.status(400).render('patientLogin', {
          message: 'Email or password is incorrect!',
          messageClass: 'alert-warning'
        });
      }
      // 最后校验密码
      const verified = bcrypt.compareSync(password, results[0].password);
      if (!verified) {
        return res.status(400).render('patientLogin', {
          message: 'Email or password is incorrect!',
          messageClass: 'alert-warning'
        });
      }

      // 复用第一次查询结果,无需二次查询
      const sess = req.session;
      sess.patient = {};
      sess.patient.city = results[0].city;
      sess.patient.name = results[0].first_name;
      sess.patient.ids = results[0].patient_id;
      const patientSess = Object.assign({}, sess.patient);

      const id = results[0].id;
      const token = jwt.sign({ id }, process.env.JWT_SECRET, {
        expiresIn: process.env.JWT_EXPIRES_IN
      });
      console.log("Token is: " + token);

      const cookieOptions = {
        expires: new Date(
          Date.now() + process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
        ),
        httpOnly: true
      }
      res.cookie('jwt', token, cookieOptions);
      res.status(200).redirect("/searchDoctor");
    })

  } catch (error) {
    console.log(error);
    res.status(500).render('patientLogin', {
      message: '服务器内部错误',
      messageClass: 'alert-danger'
    });
  }
}

优化建议

  • 推荐使用bcrypt.compare异步方法替代同步方法,避免阻塞NodeJS事件循环
  • 可以将回调式的db.query封装为Promise,结合async/await使用,避免回调嵌套,代码逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:36:07