How to authenticate via email rather than username in passport.js?

Viewed 6846

I am currently using this code for logging in:

passport.use(new localStrategy({
  usernameField: 'username'
}, User.authenticate()));

That works fine when I login with username and password. Now I want to login with email rather than username. I've changed my code to this:

passport.use(new localStrategy({
  usernameField: 'email',
  usernameQueryFields: ['email']
}, User.authenticate()));

I've also changed my HTML code to display email field with the name of email:

<input type="text" name="email" id="email" placeholder="Your Email" class="form-control">

and here's my users' schema:

{
    "_id" : ObjectId("585f62d63158ec1f608f82a2"),
    "salt" : "d7fd24ab337be7341bb6c54df69eccdce607a6cffc8457be4d44",
    "hash" : "(long text)",
    "username" : "joseph320",
    "email" : "joseph@gmail.co",
    "name" : "joseph",
    "__v" : 0,
}

So now it should look for email field in database and compare that with the email user provided in login form. But it doesn't work. When I try to login with email and password it gives me 'invalid username or password' error.

But when I am try to login with the username and the exact password it will successfully log me in. Where is the problem and how can I solve the problem?

I am using this packages for authentication:

"passport": "^0.3.2",
"passport-local": "^1.0.0",
"passport-local-authenticate": "^1.2.0",
"passport-local-mongoose": "^4.0.0",
3 Answers

I struggled with this one for a bit. It's important that you have the usernameField defined in TWO places:

  1. When creating your localStrategy (as in Joseph's original question):

    passport.use(new localStrategy({
      usernameField: 'username'
    }, User.authenticate()));
    
  2. When defining your user model (as in robertklep's answer):

    userSchema.plugin(passportLocalMongoose,
    { usernameField : 'email'});
    
Related