Yavor
Yavor

Reputation: 149

bcrypt.compare always returns false when comparing passwords

For some reason bcrypt.compare stopped working and doMatch always returns false. I'm able to create new users with hashed password but then cannot log in for the aforementioned reason. My login controller is:

  const postLoginController = async (req, res) => {
  const email = req.body.email;
  const password = req.body.password;
  try {
    User.findOne({ email: email }).then((user) => {
      console.log('password, user.password', password, user.password);
      bcrypt.compare(password, user.password).then((doMatch) => {
        console.log('doMatch', doMatch);
        //Comparing the password the user entered with the password stored in the db
        if (doMatch) {
          console.log('passwords match');
          req.session.isLoggedIn = true;
          req.session.user = user;
          req.session.save();
          res.status(200).json({ isLoggedIn: true, message: 'Logged in!' });
        } else {
          res
            .status(401)
            .json({ isLoggedIn: false, message: 'Invalid credentials. Please try again.' });
        }
      });
    });
  } catch (err) {
    res.status(400).json({ error: 'Failed to login.' });
  }
};

The console.log returns both the string and the hashed passwords:

password, user.password 123456 $2a$12$9YqCOmycoiLJ8uf7HfL4HebR2hHrJ7b2e6YspG7cP8.6UeAbapHEm

However, as I mentioned, comparing them results in doMatch always being false. Any idea why this is happening? It was working previously. I reinstalled bcryptjs, which is at version 2.4.3 currently, but it didn't help.

I'm adding the hashing code (the controller that creates the hashed password) as well:

const postSignupController = async (req, res) => {
  const email = req.body.email;
  const password = req.body.password;
  try {
    User.findOne({ email: email }).then((userDoc) => {
      if (userDoc) {
        res.status(409).json({ isLoggedIn: false, message: 'The user already exists.' });
        return;
      } else {
        res.status(200).json({ isLoggedIn: true, message: 'Signed up' });
        return bcrypt.hash(password, 12).then((hashedPassword) => {
          const user = new User({
            email: email,
            password: hashedPassword,
            cart: { items: [] },
          });
          return user.save();
        });
      }
    });
  } catch (err) {
    res.status(400).json({ error: 'Failed to sign up.' });
  }
};

Upvotes: 1

Views: 92

Answers (1)

Yavor
Yavor

Reputation: 149

I discovered the problem and fixed it. I was sending the email as a password on user creation with axios:

await axios
      .post(`/auth/signup`, {
        email: state.userEmail,
        password: state.userEmail, //should be state.userPassword
      })

It was a typo on the frontend and I spent hours trying to fix it on the backend. So, I was hashing the mail instead of the password and then trying to login with the password. Logging with the email as password worked.

As a result of this, in the postSignupController, I was receiving the email here:

const password = req.body.password;

Upvotes: 1

Related Questions