node.jspassport.jspassport-local

Passport authenticate is always executing failureRedirect


I am using passport.js to authenticate users for my node.js backend for my app. The following code is always performing failureRedirect and I am not able to find the reason for it. There is no error message.

router.post('/login', passport.authenticate('local', {
                                                    failureRedirect: '/users/login',
                                                    failureFlash: 'Invalid email or password'
                                                }), function(req, res) {
console.log('Authentication Successful');
req.flash('success', 'You are logged in ');
res.redirect('/');
});

I copied this code from the passport website and this too is not working:

router.post('/login', passport.authenticate('local', { successRedirect: '/',
                                                failureRedirect: '/users/login' }));

The following code is not even starting:

passport.use(new localStrategy({
                            email: 'email',
                            password: 'password'
                            }, function(email, password, done) {
User.getUserByEmail(email, function(err, user) {
    if (err) throw err;
    if (!user) {
        console.log('Unknown User');
        return done(null, false, {
            message: 'Unknown User'
        });
    }

    User.comparePassword(password, user.password, function(err, isMatch) {
        if (err) throw err;
        if (isMatch) {
            return done(null, user);
        } else {
            console.log('Invalid Password');
            return done(null, false, {
                message: 'Invalid Password'
            });
        }
    });
});
}));

Rest of the relevant code:

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
    done(err, user);
});
});


module.exports.getUserByEmail = function(email, callback){
var query = {email: email}; 
  User.findOne(query, function(err, user) {
    callback(err, user);
  }); 
}

module.exports.getUserById = function(id, callback){
  User.findById(id, function(err, user) {
    callback(err, user);
  }); 
}

module.exports.comparePassword = function(userPassword, hash, callback){
  console.log("pwd: " + userPassword + " hash: " + hash);
  bcrypt.compare(userPassword, hash, function(err, isMatch) {
    if(err) return callback(err);
    callback(null, isMatch);
  });
}

Solution

  • Try changing your localStrategy configuration by this one

    The default login variable name that express uses is 'username' and 'password'. In case they have to be changed, as it is 'email' in the above case then the code should be modified in the following way:

    passport.use(new localStrategy({usernameField: 'email'}, function(username, password, done){
      User.getUserByEmail(username, function(err, user){
      //rest of the code
    

    Without the change in the usernamefield, the localStrategy searches for 'username' but it does not find it hence, it redirects. Now when the usernameField is changed, it finds the 'email' and uses this in place of username to do the authentication.