user3403827
user3403827

Reputation:

bcrypt compareSync always returns false

Good day,

I am unable to login as bcrypt compareSync always returns false:

router.post('/authenticate', function(req, res, next){
    User.findOne({username: req.body.username}, function(err, user){
        //handling errors
        if(!bcrypt.compareSync(req.body.password, user.password)){
            return res.status(401).json({
                success: false,
                message: 'Invalid login credentials!'
            });
        }
        const token = jwt.sign({user: user}, 'secret', {expiresIn: 7200});
        res.status(200).json({
            success: true,
            message: 'Successfully logged in',
            token: token,
            userId: user._id
        });
    });
});

And here is how i define the user upon account creation:

    var user = new User({
        username: req.body.username,
        password: bcrypt.hashSync(req.body.password, 10),
        email: req.body.email
    });

And the error received when trying to login:

Response {_body: "{"success":false,"message":"Invalid login credentials!"}", status: 401, ok: false, statusText: "Unauthorized", headers: Headers, …}

Upvotes: 1

Views: 2791

Answers (2)

ajbieber
ajbieber

Reputation: 729

I honestly don't see anything wrong with your code....

I assume you are also using mongoose based on your findOne function. I did almost exactly what you did, but I handled the hashing in my model, rather than passing a hashed value to the model. You can do it like this:

User Model

password: 
  set: function(v) {
    return bcrypt.hashSync(v, 10);
  }

I cannot guarantee this will work for you since I'm not 100% sure if you are using Mongoose. It's worth a shot though.

Good luck!

Upvotes: 0

Jon Ribeiro
Jon Ribeiro

Reputation: 21

How I implemented bcrypt integration in the model:

import * as mongoose from "mongoose";
import * as bcrypt from "bcryptjs";

export interface IUser extends mongoose.Document {
    name: string;
    username: string;
    password: string;
    comparePassword(candidatePassword: string): Promise<boolean>;
}

export const schema = new mongoose.Schema({
    name: String,
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    }
}, { timestamps: { createdAt: "created_at", updatedAt: "updated_at" } });

schema.pre("save", function (next) {
    bcrypt.hash(this.password, 10, (err, hash) => {
        this.password = hash;
        next();
    });
});

schema.pre("update", function (next) {
    bcrypt.hash(this.password, 10, (err, hash) => {
        this.password = hash;
        next();
    });
});

schema.methods.comparePassword = function (candidatePassword: string): Promise<boolean> {
    let password = this.password;
    return new Promise((resolve, reject) => {
        bcrypt.compare(candidatePassword, password, (err, success) => {
            if (err) return reject(err);
            return resolve(success);
        });
    });
};

export const model = mongoose.model<IUser>("User", schema);

export const cleanCollection = () => model.remove({}).exec();

export default model;

Full example: https://jonathas.com/token-based-authentication-in-nodejs-with-passport-jwt-and-bcrypt/

Upvotes: 1

Related Questions