Node.js bcrypt 比较返回 false 以获得正确的密码

Posted

技术标签:

【中文标题】Node.js bcrypt 比较返回 false 以获得正确的密码【英文标题】:Node.js bcrypt compare returns false for correct password 【发布时间】:2018-02-01 03:39:14 【问题描述】:

我正在使用 bcrypt 来哈希和比较用户密码,但是在我注册新用户然后尝试登录后,即使密码正确,bcrypt 比较函数也会返回 false。

1) 创建新用户

function NewUser(request, reply) 
    let e = decodeURIComponent(request.params.q_email)
    let p = decodeURIComponent(request.params.q_password)

    dbCheckUserExists(e,
    (yes) => 
        return reply("User already exists")
    ,
    (no) => 
        bcrypt.hash(p, 3, (err, hash) => 
            if (err) 
                return reply("Error creating new user")
             else 
                dbCreateUser(request, reply, e, hash)
            
        );
    );


function dbCreateUser(request, reply, email, pwdHash) 
    var sql = "INSERT INTO Users(Version, Email, Password, Balance) VALUES (?,?,?,?)"
    var args = [1, email, pwdHash, 0]
    sql = mysql.format(sql, args)
    executeSql(sql,
        (err, rows, fields) => 
            if (err) 
                return reply("Error creating new user")
             else 
                return reply("Successfully created new user")
            
        
    );

2) 登录

function dbLogin(request, reply, yes, no) 
    let e = decodeURIComponent(request.payload.q_email)
    let p = decodeURIComponent(request.payload.q_password)
    //reply('email: ' + e + ' password: ' + p)

    var sql = "SELECT Password FROM Users WHERE Email = ? LIMIT 1"
    sql = mysql.format(sql, e)

    executeSql(sql,
        (err, rows, fields) => 
            if (err) 
                throw err
             else 
                if (rows.length == 0) 
                    //no()
                    reply("email not found")
                 else 
                    bcrypt.compare(p, rows[0].Password, (err, res) => 
                        if (res == true) 
                            reply("correct password")
                            //dbCreateSession(request, reply, yes, no)
                         else if (res == false)
                            reply("incorrect password: " + p + " " + rows[0].Password)
                        
                        else 
                            //no()
                            reply("neither true nor false")
                        
                    );
                
            
        
    );

我用电子邮件“hello”和密码“world”创建了一个用户并运行以下查询

SELECT Email, Password FROM `Users` WHERE Email = 'hello'

返回以下内容

hello   $2a$04$JwaMtM577eqLRNd0m5tbTewP1IxBMSAwyW9kczPjOPjDgu9I

但是,当我尝试登录时,我得到以下(自定义响应)

incorrect password: world $2a$04$JwaMtM577eqLRNd0m5tbTewP1IxBMSAwyW9kczPjOPjDgu9I

谁能看出我哪里出错了?

【问题讨论】:

【参考方案1】:

我一直盯着屏幕太久了!

问题是数据库中的密码字段被截断(55 个字符而不是 60 个字符)

【讨论】:

【参考方案2】:

增加数据库中密码字段的大小,即

varchar(125)

【讨论】:

【参考方案3】:

也许你最终得到了一个无效的哈希值,尝试使用 bcrypt 生成哈希值:

bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) 
  // Store hash in your password DB. 
);

然后,您可以尝试以简单的方式检查数据库中的哈希是否与您将使用的输入的硬编码版本匹配(密码变量:p 作为字符串'world'

bcrypt.compare('world', hash, function(err, result) 
 if (err)  throw (err); 
 console.log(result);
);

如果它有效(它可能会),然后尝试对来自请求的输入执行相同的操作。

您应该更深入地了解问题所在。

【讨论】:

以上是关于Node.js bcrypt 比较返回 false 以获得正确的密码的主要内容,如果未能解决你的问题,请参考以下文章

bcrypt-nodejs 比较方法每次都返回 false

bcrypt 哈希加密的问题 - node.js

等待 bcrypt.compare(req.body.password, user.password) 返回 false

Nodejs bcrypt比较无法正常工作

Golang 中的 Bcrypt 密码散列(与 Node.js 兼容)?

Node.js Mongoose 使用 bcrypt 登录