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

Bcrypt compare方法始终返回false,请求排查代码问题

Bcrypt Compare始终返回false的问题排查与修复

问题1:注册表单重复的name属性导致密码被错误处理

注册视图中,密码输入框和确认密码输入框的name属性都设置为password,这会导致表单提交时,req.body.password是一个包含两个值的数组(比如用户输入1234两次,req.body.password就是["1234", "1234"])。而你在加密时调用了password.toString(),最终加密的是"1234,1234"这个字符串,和登录时用户输入的单个密码自然无法匹配。

修复方案:

修改注册视图的确认密码输入框name属性,改为confirmPassword:

<div class="form-group">
    <input type="password" name="confirmPassword" class="form-control" id="confirmPassword" placeholder="Confirm Password">
</div>

同时在server.js的注册接口中,增加密码一致性校验(可选但推荐):

server.post('/registration', async(req, res) => {
    const { firstName, lastName, email, password, confirmPassword } = req.body
    // 新增密码一致性校验
    if (password !== confirmPassword) {
        return res.render('registration.ejs', { messages: { error: '两次输入的密码不一致' } })
    }
    await bcrypt.hash(password.toString(), salt)
        .then((hashedPassword) => {
            users.push({
                id: Date.now().toString(),
                email: email,
                password: hashedPassword,
                firstName: firstName,
                lastName: lastName
            })
            console.log(users)
            res.redirect("/login")
        })
        .catch((error) => {
            console.log(error);
            res.render('registration.ejs', { messages: { error: '注册失败,请重试' } })
        });
})

问题2:Passport认证函数未调用done回调

在passport.js的authenticateUsers函数中,调用bcrypt.compare后,无论对比结果是成功还是失败,都没有调用Passport要求的done回调函数。这会导致Passport无法获取认证结果,即使密码对比成功,也无法完成登录流程,同时你看到的compare返回false可能是因为之前的密码错误,而这个问题会进一步导致认证逻辑完全失效。

修复方案:

修改passport.js中的authenticateUsers函数,在bcrypt.compare的回调中调用done:

const authenticateUsers = async(email, password, done) => {
    const user = await getUserByEmail(email)
    console.log("THE Password BEFORE COMPARISON ---> " + password)
    console.log(user)
    if (user == null) {
        console.log("user null;;;lllll")
        return done(null, false, { message: "用户未注册" })
    }
    bcrypt.compare(password.toString().trim(), user.password, function(err, result) {
        console.log("THE PASSWORD AFTER COMPARISON ---> " + password)
        console.log(user)
        if (err) {
            console.log(err)
            return done(err) // 传递错误给Passport
        }
        if (result) {
            console.log("PASSWORD MATCHES")
            return done(null, user) // 认证成功,传递用户信息
        } else {
            console.log("DOESNOT MATCH")
            return done(null, false, { message: "密码错误" }) // 认证失败,返回错误信息
        }
    })
}

额外优化建议

  • 避免全局固定salt:bcrypt.hash可以自动生成salt,不需要手动调用bcrypt.genSaltSync,直接使用await bcrypt.hash(password, 10)即可,更安全。
  • 处理getUserByEmail的异步逻辑:虽然当前users是内存数组,find是同步方法,但如果后续改用数据库,建议保持异步风格,确保代码可扩展。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:46:27