I am having an issue with compare if the hashed password comes from my database. Below is a snippet of my auth model:
const db = require('../db/db');
const bcrypt = require('bcrypt');
module.exports = {
signUp: (req, res) => {
var firstName = req.body.firstName;
var lastName = req.body.lastName;
var username = req.body.username;
var plainPassword = req.body.password;
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(plainPassword, salt, (err, hash) => {
db.connection.query('INSERT INTO database.Users VALUES ("' + firstName + '","' + lastName + '","' + username + '","' + hash + '")', (err, result) => {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
});
});
},
login: (req, res) => {
var username = req.body.username;
var plainPassword = req.body.password;
var hashedPassword;
db.connection.query('SELECT password FROM database.Users WHERE username = "' + username + '" ', (err, result) => {
if (err) {
console.log(err);
} else {
hashedPassword = result[0].password;
bcrypt.compare(plainPassword, hashedPassword, (err, result) => {
if (err) {
console.log('bcrypt - error - ', err);
} else {
console.log('bcrypt - result - ', result);
}
});
}
});
}
}
example input/output for hashing function:
input = 'pass'
output = '$2a$10$5QhupowO35FD20MCyKwFbOFAhYbVf27oV81nzT'
I can compare the plain text password to the hashed password and the result would be true.
If I store the hashed password in my database and then compare them, the result will always be false. This is happening with any password. There is no error, it just believes that the plainPassword does not match the hashed one.
I can store a plaintext password to the database and compare it to the same word and everything is good. The result I get from the database is a string so that isn't the problem. The compare method just doesn't like the bcrypt hash that comes from the database.
Any ideas?
Looks like a character set issue to me. If that's SQL, then try setting charset for the connection and the table to UTF-8
I set both the connection and the table to UTF-8 but I am still having the same problem. Thank you for the suggestion. Any other ideas?
Then it must be some other issue with your schema or the manner you are storing. Stack overflow is a better place to ask such questions.
@mtterranova Have you tried outputting the retrieved hash and the supplied password to the console? I actually had a similar problem in the past, where it was merely a matter of not validating the input properly (in this case, it was that the client did not give any passwords at all).
Closing this as it is not an issue with this module (from what I can tell so far) and more of a support issue. Others can continue to comment to provide support.
I have the same issue.
@shovon I checked output in console and all right, but if compare hash from console in https://www.dailycred.com/article/bcrypt-calculator was do not match.
@mtterranova Wow. I just realized what the problem is with your code: the hash is being truncated upon insertion. The length of a bcrypt hash is typically 60 characters, but the hash that you provided is 45.
Please update your table schema so that the column that stores the password hash can store strings with lengths of at least 60 characters.
@solofeed paste in your code here, perhaps?
This is pre save action.
/**
* Encrypt password if new user or modified password
*/
userSchema.pre('save', function saveHook(next) {
let user = this;
// proceed further only if the password is modified or the user is new
if (!user.isModified('password')) return next();
return bcrypt.hash(user.password, 10, (hashError, hash) => {
if (hashError) {
return next(hashError);
}
// replace a password string with hash value
user.password = hash;
return next();
});
});
Compare the passed password with the value in the database. A model method.
userSchema.methods.comparePassword = function comparePassword(password, callback) {
bcrypt.compare(password, this.password, callback);
};
And login strategy
module.exports = new PassportLocalStrategy({
usernameField: 'email',
passwordField: 'password',
session: false,
passReqToCallback: true
}, (req, email, password, done) => {
let userData = {
email: email.trim(),
password: password.trim()
};
// find a user by email address
return User.findOne({email: userData.email}, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
let error = new Error('Incorrect email or password');
error.name = 'IncorrectCredentialsError';
return done(error);
}
// check if a hashed user's password is equal to a value saved in the database
return user.comparePassword(userData.password, (passwordErr, isMatch) => {
if (err) {
return done(err);
}
if (!isMatch) {
let error = new Error('Incorrect email or password');
error.name = 'IncorrectCredentialsError';
return done(error);
}
let payload = {
sub: user._id
};
// create a token string
let token = jwt.sign(payload, config.authSecretKey, {
expiresIn: '7d'
});
let data = {
name: user.username,
email: user.email,
role: user.role
};
return done(null, token, data);
});
});
});
@solofeed for formatting code, use triple back ticks rather than only a single back tick, like so:
```
<code goes here...>
```
@shovon, you have any ideas why compare method return false?
@shovon Sry, was my syntax error. Now all right.
Closing this issue. This question is best for stack overflow. I suggest debugging/printing the inputs you are passing into the bcrypt functions to verify they are indeed what you think they are. Also check the types of the inputs becuase just printing them may convert them to strings.
For anyone who is stuck, check to make sure that the hash is the second argument and the supplied password is the first. Hope it helps someone!
i have the same error
but @solofeed you did not explained the error you corrected
@RASHID-TP I remember it was a problem with the package manager and OS
It depends where you installing you dependencies, because when I used yarn on mac os and then push to the server, and CI run yarn install from lock my version, it was a bug, because the package was installed on mac os, and some OS features do not work on another OS
Note, this my opinion, and just try to check this theory
Reinstall all dependencies helped me in the past
thank you....its cleared
On Wed, 20 Mar 2019, 1:04 a.m. Eugene <[email protected] wrote:
@RASHID-TP https://github.com/RASHID-TP I remember it was a problem
with the package manager and OSIt depends where you installing you dependencies, because when I used yarn
on mac os and then push to the server, and CI run yarn install from lock my
version, it was a bug, because the package was installed on mac os, and
some OS features do not work on another OSNote, this my opinion, and just try to check this theory
Reinstall all dependencies helped me in the past
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/kelektiv/node.bcrypt.js/issues/466#issuecomment-474726765,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ArowuKYEMlUY7FgFr4BUgbyWs4mPyE8Yks5vYeufgaJpZM4LPSut
.
i need to BCrypt pass convert plain text without compare so it's possible
@solofeed I am facing the same issue. Did you ever find a solution?
@Vishal23016 Bcrypt is not an encryption technique, its a hashing technique. So you can't ever get back the original string from the hash. It's a one-way method.
For anyone who is stuck, check to make sure that the hash is the second argument and the supplied password is the first. Hope it helps someone!
YOU ARE A SAINT!
I had been going crazy over this for at least an hour now!!!!!
Most helpful comment
@mtterranova Wow. I just realized what the problem is with your code: the hash is being truncated upon insertion. The length of a bcrypt hash is typically 60 characters, but the hash that you provided is 45.
Please update your table schema so that the column that stores the password hash can store strings with lengths of at least 60 characters.