3

I am unable to get Passport to authenticate my user. For some reason the passport.authenticate method always fails. What I don't understand is that if I add middleware before the passport call, the user data is accessible via req.user.

Any ideas to why passport.authenticate is failing?

app.get('/app'
  // MY USER SHOWS UP HERE
  , function(req, res, next) {
    console.log("app.get('/app')", req.user);  
    next();
  }

  // DOESN'T MAKE IT PAST HERE
  , passport.authenticate('local', { failureRedirect: '/login', failureFlash: true })

  // NEVER MAKES IT HERE
  , function(req, res) {   
    console.log('FTW!!!');
    res.render('../../client/app/app')
  }
);

Authentication code

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
  function(email, password, done) {
    console.log("Authenticating user: ", email, password);
    User.findOne({ email: email }, function (err, user) {
      if (err)   return done(err);
      if (!user) return done(null, false, { message: 'Invalid Email' });

      return user.authenticate(password, function(err, valid) {
        if (err)    return done(err);
        if (!valid) return done(null, false, { message: 'Invalid Password' });
        return done(null, user);
      });
    });
  }
));

passport.serializeUser(function(user, done) {
  console.log('Serializing: ', user);
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  console.log('Deserializing: ', id);
  User.findById(id, function (err, user) {
    done(err, user);
  });
});

Signup and redirect: Note the ['Missing Credentials'] message after it has found the user

// SIGN UP
Authenticating user:  cacky23@acme.org.com foobar
User.authenticate(): Comparing...  // user.authenticate()
Compare Complete... true           // bcrypt compare
Serializing:  { email: 'cacky23@acme.org.com',
  password: '$2a$10$TJcvr4wtgs6DFaNnyQSLt.v5GLbt8PIi.oOlgqZpvghveKEPEcroW',
  _id: 52160e247d0aa8e328000001,
  __v: 0,
  createdAt: Thu Aug 22 2013 07:12:04 GMT-0600 (MDT) }
POST /users 302 185ms - 64b
Deserializing:  52160e247d0aa8e328000001
Found User:  { email: 'cacky23@acme.org.com',
  password: '$2a$10$TJcvr4wtgs6DFaNnyQSLt.v5GLbt8PIi.oOlgqZpvghveKEPEcroW',
  _id: 52160e247d0aa8e328000001,
  __v: 0,
  createdAt: Thu Aug 22 2013 07:12:04 GMT-0600 (MDT) }

// MY TEST MIDDLEWARE 
app.get('/app') { email: 'cacky23@acme.org.com',
  password: '$2a$10$TJcvr4wtgs6DFaNnyQSLt.v5GLbt8PIi.oOlgqZpvghveKEPEcroW',
  _id: 52160e247d0aa8e328000001,
  __v: 0,
  createdAt: Thu Aug 22 2013 07:12:04 GMT-0600 (MDT) }
GET /app 302 6ms - 68b
Deserializing:  52160e247d0aa8e328000001
Found User:  { email: 'cacky23@acme.org.com',
  password: '$2a$10$TJcvr4wtgs6DFaNnyQSLt.v5GLbt8PIi.oOlgqZpvghveKEPEcroW',
  _id: 52160e247d0aa8e328000001,
  __v: 0,
  createdAt: Thu Aug 22 2013 07:12:04 GMT-0600 (MDT) }
[ 'Missing credentials' ]
GET /login 200 85ms - 3.65kb
laggingreflex
  • 32,948
  • 35
  • 141
  • 196
chris
  • 4,332
  • 5
  • 41
  • 61

1 Answers1

3

How does passport authentication fail? Does it throw an error, or does the app crash?

Try to use req.isAuthenticated() to check whether the user is logged in. I use passport.authenticate only while login when login credentials are provided in a http post request.

So on /app use only

if(req.isAuthenticated()) {
    console.log('user logged in', req.user);
    next();
}
else {
   console.log('user not logged in');
}

And on /app/login you can use the code you already have. Right now you're probably already logged in. Try to delete the cookie. After that it probably doesn't log the user object on console.log(req.user) anymore.

Besides that all your code looks correct. So if isn't working, try to strip down your code. We don't know what code you have in user.authenticate. Is that function working?

Regards

Marc Bachmann
  • 113
  • 1
  • 7
  • It fails within the middleware and redirects the user to /login (specified by the failureRedirect). The user model, which is my custom model returned by the deserializer method doesn't have an isAuthenticated method, but a user is returned. user.authenticate does work properly on login (console log statments have shown). – chris Aug 22 '13 at 13:13
  • It looks like you were mostly right, except what was probably a typo. It should be req.isAuthenticated() which can be seen in the example https://github.com/jaredhanson/passport-local/blob/master/examples/login/app.js. If you can edit your suggestion I will mark it as being the solution. – chris Aug 23 '13 at 03:42
  • Sorry for the typo. I updated req.user.isAuthenticated() to req.isAuthenticated(). – Marc Bachmann Aug 24 '13 at 10:51