2
votes

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.

1
what do you mean by does not work ? Do you get any error ? or does the execution just hang ? btw passport has a cool middleware that you can usekranthi117
Basically, if(!user) condition within passport.authenticate code is executing no matter what..even if the email and password are correct. This all worked when I had seperate username field and was authenticating using that. As soon as I switched to email its not logging me in. No it doesnt hang and no I dont get any error. I just get 'user not found' as in that !user conditionRajat Bansal
may be the user is actually null. Did you inspect the value of email and user ? Try renaming the email field in your model (and all references to it). This helped me with a similar issuekranthi117
@kranthi117: I had consoled log the user value and its coming out to be false. Are you saying rename the email to username and try using email instead but just name it username?Rajat Bansal
@abdulbarik : Yes I just did. It doesnt console.log anything..not even the words i used as string..means its not even going there I believeRajat Bansal

1 Answers

0
votes

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.