Unable to authenticate using email with passport-local nodejs..tried several examples

Rajat Bansal Source

I have been trying to use email and password to authenticate using passport-local. I had similar code when I was using username and it worked fine. With email, I made some changes however nothing is working. Right at the endpoint '/login' of type 'post' the condition !user condition in users.js (shown below as 2nd code snippet) is somehow executing. Its not even going inside passport.use. Following is the code:- In user.js(model file),

var mongoose=require('mongoose');
var bcrypt=require('bcryptjs');

//user schema
var UserSchema=mongoose.Schema({
    phone: {
        type:String,        

    },
    email:{
        type: String,
        index:{unique:true}
    },
    password:{
        type: String
    },
    firstname:{
        type: String
    },
    lastname:{
        type: String
    } 
});
var User=module.exports = mongoose.model('User',UserSchema);


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

module.exports.comparePassword=function(candidatePassword, hash, callback){
    bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
    callback(null,isMatch);
  });
}

}

In users.js(where i specify routes):

var express = require('express');
var router = express.Router();
var bodyParser=require('body-parser');
var User=require('../models/user');
var passport=require('passport');
var localStrategy=require('passport-local').Strategy;

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { 
      return next(err);
    }
    if (!user) {   /*this is where the problem is this code executes everytime*/
      return res.send('User not found'); 
    }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.json(user);
    });
  })(req, res, next);
});

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

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

//this doesnt seem to work
passport.use(new localStrategy({usernameField:'email', passwordField:'password'},function(email,password,done){
    User.getUserByUsername(email, function(err,user){
      if(err) throw err;
      if(!user){
        return done(null,false,{message: 'User not found'});
      }

      User.comparePassword(password, user.password, function(err, isMatch){
        if(err) return done(err);
        if(isMatch){
          return done(null, user);
        }
        else{
          return done(null,false,{message: 'Password doesnt match our records'});
        }
      });
    });

  }));

Note that there is no front end on this. I am just using postman to test my apis.

node.jspassport.jspassport-local

Answers

answered 2 years ago Rajat Bansal #1

This code works fine with emails. The issue was I also have another file called admin.js and admins.js which do the same task as user and users. However, admin makes use of username. I had the same passport.use code for admin however, users was trying to access that file instead of the current one. Once I removed the admin code it all worked.

comments powered by Disqus