Nikhil R
Nikhil R

Reputation: 115

Why am I getting isMatch null from bcrypt compare even though two password string matches perfectly?

I'm trying to authenticate the user based on a password. I'm using bcrypt compare to compare user requested password and one in mongodb but even though two password matches perfectly I get null value, here is the code which I"m trying

userSchema.methods.comparePassword = function (passw, cb) {
    var user = this;
    console.log((passw === user.password) ? 'passwords match' : 'passwords dont match' );
    bcrypt.compare(passw, user.password, function (err, isMatch) {
        console.log(passw +" "+ user.password +" " +isMatch )
        if(err) {
            return cb(err)
        }
        cb(null, isMatch)
    })
}

I get the console output as below

sh37xb sh37xb null

which are user-entered password, password in database for that user, and isMatch value which is null instead it has to be the opposite since both passwords match perfectly. when I checked this password with the ternary condition it says 'passwords match' but not with bcrypt.compare. What am I doing wrong? can anyone help me to point out my mistake??

Upvotes: 0

Views: 1121

Answers (2)

kallis
kallis

Reputation: 133

When the user signup you save the hashed version of it not the actual text.

const password = req.body.password
// This hasedPassword will be saved to database
const salt = await bcrypt.genSalt(10)
const hashedPassword = await bcrypt.hash(password, salt)

When the user tries to log in, bcrypt compare the user-entered password to the hashedPassword

const saveHashedPassword = user.password
const enteredPassword = passw
bcrypt.compare(enteredPassword, saveHashedPassword, function(err, result) {
    // Do your logic
    if(err) {
            return cb(err)
    }
    cb(null, isMatch)
})

Upvotes: 2

Paul
Paul

Reputation: 27433

The 2nd parameter to bcrypt.compare should be hashed and not a plain text string.

Bcrypt compare does not compare a plain text password with another plain text password. It calculates the hash of a plain text password and compares that with an earlier hash that you supply as the 2nd parameter to see if the hashes match.

The typical reason for using bcrypt compare is that it is more secure than string comparison. For that to be true, the password database needs to contain hashed passwords, not plain text passwords. A database of plain text passwords is a tempting thing to steal. A database of hashed strings is less useful.

The npm page for bcrypt gives this example:

To check a password:
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
    // result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
    // result == false
});

Upvotes: 1

Related Questions