小能豆

Bcrypt compare() always return false

javascript

I have used this code for comparison.

UserSchema.pre('save', async function() {
    const salt = await bcrypt.genSalt(10)
    this.password = await bcrypt.hash(this.password, salt)
})

UserSchema.methods.comparePassword = async function(candidatePassword) {
    const isMatch = await bcrypt.compare(candidatePassword, this.password)
    console.log(this.password);
    console.log(candidatePassword);
    return isMatch
}

I always get an invalid credentials error from the below login function. I have checked by logging the outputs. The problem lies with the compare password functionality.

const login = async(req, res) => {
    const { email, password } = req.body

    if (!email || !password) {
        throw new CustomError.BadRequestError('Please provide email and password')
    }

    const user = await User.findOne({ email })

    if (!user) {
        throw new CustomError.UnauthenticatedError('Invalid Credentials')
    }

    const isPasswordCorrect = await user.comparePassword(password)

    if (!isPasswordCorrect) {
        throw new CustomError.UnauthenticatedError('Invalid Credentials')

    }

    if (!user.isVerified) {
        throw new CustomError.UnauthenticatedError('Please Verify Your Email ')
    }

    const tokenUSer = createTokenUser(user)
    attachCookiesToResponse({ res, user: tokenUSer })

    res.status(StatusCodes.OK).json({ user: tokenUSer })

}

阅读 79

收藏
2023-11-30

共1个答案

小能豆

If you’re getting an “Invalid Credentials” error consistently, it suggests that the comparePassword method is not returning the expected result. Here are a few things you can check and try to identify the issue:

  1. Console Logging: You’ve already added some console.log statements, but make sure to log the values of this.password and candidatePassword inside the comparePassword method. This will help you verify whether the passwords are being compared correctly.

```
UserSchema.methods.comparePassword = async function(candidatePassword) {
console.log(‘Stored Password:’, this.password);
console.log(‘Candidate Password:’, candidatePassword);

   const isMatch = await bcrypt.compare(candidatePassword, this.password);
   console.log('Is Password Match?', isMatch);

   return isMatch;

}
```

Check the logs and make sure that both passwords are being logged correctly.

  1. Ensure Password Hash: When saving the password using the pre('save') hook, make sure that the this.password is actually being hashed correctly. Log the hashed password to ensure it’s not empty or incorrect.

UserSchema.pre('save', async function() { const salt = await bcrypt.genSalt(10); this.password = await bcrypt.hash(this.password, salt); console.log('Hashed Password:', this.password); });

Verify that the hashed password is logged correctly.

  1. Compare with Plain Text Password: As a debugging step, try comparing the stored hashed password with the plain text password directly (without using bcrypt.compare). This is just for debugging purposes and should not be used in production.

UserSchema.methods.comparePassword = function(candidatePassword) { return this.password === candidatePassword; }

If this comparison works, it indicates that the issue might be with the bcrypt.compare method.

  1. Check for White Spaces: Ensure that there are no leading or trailing white spaces in the stored hashed password or the candidate password. You can trim both before comparing.

```
UserSchema.methods.comparePassword = async function(candidatePassword) {
const trimmedStoredPassword = this.password.trim();
const trimmedCandidatePassword = candidatePassword.trim();

   const isMatch = await bcrypt.compare(trimmedCandidatePassword, trimmedStoredPassword);
   return isMatch;

}
```

Try these steps and see if you can identify the source of the issue. If the problem persists, it might be worth checking the version of the bcrypt library you are using, as updates or changes to the library might affect its behavior.

2023-11-30