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

登录时Bcrypt密码比对始终返回无效 即便输入密码正确

问题定位

你这个代码有个非常典型的低级错误,直接导致所有比对逻辑失效:

  • 变量名覆盖:bcrypt.compare的回调参数你命名成了res,和外层Express的响应对象res重名了。回调里拿到的res只是个表示比对是否通过的布尔值,你在布尔值上调用.status()、.json()方法会直接抛类型错误,代码逻辑完全走歪,最后就落到返回401密码错误的分支。
  • 错误分支没加return:bcrypt运行报错的时候,你返回完错误响应没有终止函数,代码还会继续往下执行后续的比对判断,会出现一次请求返回两次响应的报错。
  • 字段名写错了:你解构返回用户信息的时候,要剔除的密码字段写的是password,但你实际存密码的字段是wachtwoord,就算登录成功,哈希密码也会随接口返回出去,有安全风险。
  • 语法错误:返回体里的new Date().toISOString没加执行括号,你传过去的是函数本身,不是执行后的时间字符串。
  • JWT签发没做错误处理:如果jwt签发过程报错,接口会直接挂住,客户端收不到任何响应。
修正后可直接用的代码
bcrypt.compare(req.body.wachtwoord, results[0].wachtwoord, function(err, isMatch) {
    if (err) {
        logger.error(err);
        return res.status(err.status || 500).json(err);
    }
    if (isMatch) {
        logger.info("passwords matched, sending userinfo and valid token.");
        // 剔除实际存储密码的wachtwoord字段,避免敏感信息泄露
        const { wachtwoord, ...userinfo } = results[0];
        const payload = { docentID: userinfo.docentID };
        logger.debug(payload);

        jwt.sign(
             payload,
             jwtSecretKey,
             { expiresIn: "25d" },
             function(err, token) {
                 if (err) {
                     logger.error("JWT sign failed: ", err);
                     return res.status(500).json({
                         status: 500,
                         message: "Login failed, please try again later.",
                         datetime: new Date().toISOString()
                     });
                 }
                 logger.info("User logged in, sending: ", userinfo);
                 return res.status(200).json({
                     status: 200,
                     result: {...userinfo, token },
                 });
             }
        );
    } else {
        logger.info("Password invalid");
        return res.status(401).json({
            status: 401,
            message: "Password invalid.",
            datetime: new Date().toISOString(),
        });
    }
});
额外排查点

如果改完还是比对失败,去检查你注册存哈希的逻辑:

  1. 确认存到数据库的bcrypt哈希没有被截断,bcrypt生成的哈希固定60位,数据库字段至少要设为VARCHAR(60),推荐直接设VARCHAR(255)留冗余。
  2. 确认存哈希的时候没有做额外的编码转换(比如全角半角转换、多余的转义),否则哈希值变了比对永远不通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:51:27