'bcrypt compareSync "Unhandled rejection Error: data and hash must be strings"
I'm using knex to select a specific users password from my database. this hashed password is returned to me in an object like this:
[ anonymous {
password_hash:
'$2a$10$zRSFdNJsg8S3Xv1I73gjYuRu.Mw/9Dtujh0dTqrtc9DA12vUHuqbK' } ]
When I try using bcrypt.compareSync to compare the entered password and the password that exists in the database, it give me an error saying data and hash must be strings. I tried using the .toString() method and JSON.stringify(password_hash). But both don't help. How do I get this to work?
Here is my code:
knex('users').where({
email: req.body.loginEmail
}).select('password_hash')
.then(function(password_hash) {
//console.log("resp", password_hash)
console.log("JSON stringifies",JSON.stringify(password_hash))
console.log("req", req.body.loginPass)
console.log('hash', password_hash)
bcrypt.compareSync(req.body.loginPass, JSON.stringify(password_hash), function(err, doesMatch){
if (doesMatch){
console.log("Passwords Match")
req.session.email = rows[0].email;
var templateVars = {
emale: req.session.email
}
res.render('/dashboard', templateVars)
} else {
console.log("THIS IS THE ERROR", err);
res.send("I DONT KNOW YOU. SIGN UP FIRSt.")
}
})
})
My entire error:
Unhandled rejection Error: data and hash must be strings
at Object.compareSync (/vagrant/CaloBoxInc/node_modules/bcrypt/bcrypt.js:144:15)
at /vagrant/CaloBoxInc/server.js:159:14
at tryCatcher (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/vagrant/CaloBoxInc/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:570:20)
at tryOnImmediate (timers.js:550:5)
at processImmediate [as _immediateCallback] (timers.js:529:5)
Solution 1:[1]
Could it be that your req.body.loginPass is not string? JSON.stringify always returns undefined / string and bcrypt returns different error if parameter is undefined so that paramater can't be the problem.
Try force casting req.body.loginPass to string like this:
bcrypt.compareSync(´´+ req.body.loginPass, ...
(just for debugging purposes... though you should already see from earlier console logs it it is not a string).
Solution 2:[2]
This error arises if one or more arguments passed to bcrypt.compareSync function are either undefined or null.
Solution 3:[3]
The solution to this problem is by changing the datatype of the password field in your Database to char(150) to avoid truncation. I hope that helps.
Solution 4:[4]
Go to your mongoose file, where you can set your types of email and password. Change type of password from Number to String.
Solution 5:[5]
In the database, the older password value was not a hashed password. It was in a String. Delete the old value in the database. Create a new one with the hashed password and then validate it. It works.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mikael Lepistö |
| Solution 2 | Sai Trinath Saka |
| Solution 3 | ShadRack Osewe |
| Solution 4 | Tomer Shetah |
| Solution 5 | ouflak |
