Reputation: 665
I am using "bcrypt": "^3.0.4"
and I have the latest stable version of node. The issue I am facing is when the user attempts to login. With the correct password the initial login attempt is always unsuccessful while the second attempt is successful. I would like to know where I am getting it wrong. The assumption here is that the user has entered an email/username that is available in the database, mongodb in this case.
User.findOne({ "email": user.email }, (err, ruser) => {
if (err) {
res.send(err);
}
else {
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
console.log(err);
}
else {
bcrypt.compare(user.password, hash).then(function (res) {
if (res) {
pass = true;
}
else {
pass = false;
}
});
res.json(pass);
}
});
}
});
Thank you in advance.
Upvotes: 1
Views: 1980
Reputation: 138
import { hash, compare } from 'bcryptjs';
export const hashPassword = async (password: string): Promise<string> => {
const hashedPassword = await hash(password, 10);
return hashedPassword;
};
Upvotes: 0
Reputation: 1463
There are two issues with your code.
bcrypt.compare
is async and the res.json
is outside of the .then, so res.json
is actually ran before comparison or pass
it set.
pass
is not defined with var
/let
, so pass
becomes a global variable and this is serious security implication, because two user logging in at the same time will cause a race condition (e.g. pass
from session A may be res.json-ed in session B)
It works as a result of the above two errors, in the first request, res.json
is executed before comparison and pass
is not set yet, so it returns null. On the second request, again res.json
is executed before compare, however this time the pass
contains the value of the last compare, so what you are getting is actually last compare's result.
In addition, it is ok if you are just testing, otherwise this code does nothing, because this code generates the hash for the given password, and compares the given password to the generated hash, which definitely should be always true.
Upvotes: 2