Dev
Dev

Reputation: 87

Bcrypt Compare Password

I'm having problem in comparing the password and yes it is storing the hash of the password correctly when I'm registering.

Database - MongoDB I'm using node.js version - v18.17.0 bcrypt version - 5.1.1

Here's my userSchema -

const userSchema = new mongoose.Schema({
    username: { type: String, required: true, unique: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
});

userSchema.pre('save', async function (next) {
    try {
        if (!this.isModified('password')) {
            return next();
        }

        const hashedPassword = await bcrypt.hash(this.password, 10);
        this.password = hashedPassword;
        return next();
    } catch (error) {
        ...
    }
})

also here's my AuthController.js file's login part -

loginUser: async (req, res) => {
        try {
            const { email, password } = req.body;

            const user = await User.findOne({ email });
            if (!user) {
                return res.status(401).json({ error: 'Invalid email or password.' });
            }

            const trimmedPassword = password.trim();

            console.log('Password received:', password);
            console.log('User password:', user.password);

            const passwordMatch = await bcrypt.compare(trimmedPassword, user.password);
            console.log(passwordMatch);

            if (!passwordMatch) {
                return res.status(401).json({ error: 'Invalid email or password.' });
            }

            // Generate a JWT token
            const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expireIn: '1h' });

            res.json({ token, userId: user._id, username: user.username });
 } catch(error){...}

I'm using postman right now to check it, postman giving me error: 'Invalid email or password', and in the terminal i'm getting -

Password received: abcd

User password: $2b$10$3XqxT29oUNX8Sr86i/woPufzHf6s7OjP4yyNdirtGk9Zj0T3MdkAC

false

Upvotes: 1

Views: 449

Answers (4)

Sanat Jain
Sanat Jain

Reputation: 1

LoginUser = async (req, res) => {
  let success = false;
  // If there are errors, return Bad request and the errors
  const errors = validationResult(req);

  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  const { email, password } = req.body;
  try {
    let user = await User.findOne({ email });
    if (!user) {
      success = false
      return res.status(400).json({ error: "Please try to login with correct credentials" });
    }

    const passwordCompare = await bcrypt.compare(password, user.password);
    if (!passwordCompare) {
      success = false
      return res.status(400).json({ success, error: "Please try to login with correct credentials" });
    }

    const data = {
      user: {
        id: user.id
      }
    }

    // console.log("hello   "+ data.user.id)
    const authtoken = jwt.sign(data, process.env.JWT_SECRET);

    success = true;
    res.json({ success, authtoken })
  } catch (error) {
    console.error(error.message);
    res.status(500).send("Internal Server Error");
  }
}

Upvotes: -1

Yan
Yan

Reputation: 1

loginUser: async (req, res) => {
    try {
        const { email, password } = req.body;

        const user = await UserModel.findOne({ email: email });
        if (!user) {
            return res.status(401).json({ error: 'Invalid email or password.' });
        }

        const trimmedPassword = password.trim();
        console.log('Password received:', password);
        console.log('User password:', user.password);

        const passwordMatch = await bcrypt.compare(trimmedPassword, user.password);
        console.log(passwordMatch);

        if (!passwordMatch) {
            return res.status(401).json({ error: 'Invalid email or password.' });
        }

        const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });

        res.json({ token, userId: user._id, username: user.username });
    } catch(error) {
        console.error(error);
        res.status(500).json({ error: 'An error occurred during the login process.' });
    }
}

Upvotes: -1

Dev
Dev

Reputation: 87

Thanks to @Savyon, I think I was hashing the password twice so I removed the hashing process from the register code part and made these changes on my user model code -

userSchema.pre('save', async function (next) {
    try {
        if (!this.isModified('password') || this.isModified('password') && typeof this.password === 'string') {
            const hashedPassword = await bcrypt.hash(this.password, 10);
            this.password = hashedPassword;
        }
        return next();
    } catch (error) {
        return next(error);
    }
})

Upvotes: 0

Savyon
Savyon

Reputation: 71

instead of comparing directly inside AuthController.js you can make sure youre accessing the right user by adding a method directly to User model (also make sure bcrypt is imported):

userSchema.methods.comparePassword = function (candidatePassword) {
    return bcrypt.compareSync(candidatePassword, this.password);
};

once you have relevant user inside AuthController.js:

const isPasswordVerified = user.comparePassword(payload.password);

Upvotes: 2

Related Questions