Send info message from verify callback to client

598 views Asked by At

I am trying to send the info message that gets set in my verify callback:

Here is the example from passport docs:

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

However if I write my route as:

app.post('/login',
  passport.authenticate('local'),
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/users/' + req.user.username);
  });

That function does not get called with the info message. At least not that I know of. I know passport shoves the user into the req, as I can access it from req.user. Is there a way to access the info message like this. Or do I need to specify a custom callback?

Which they outline as:

app.get('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});

The part that is confusing is that they outline using a 3rd parameter in the done callback (from verify) that is a message, yet you can only access that if you write a custom callback. Is that true.

1

There are 1 answers

5
Halim Qarroum On

The adopted convention in the Passport framework is that the optional info object will be available through req.authInfo.

This however depends on the used strategy which is responsible for passing it to the Passport framework. For instance, the passport-http strategy does not forward the info object to Passport while the passport-local does.

Here is how you can then access it in a controller protected by the local strategy :

app.post('/login',
  passport.authenticate('local'),
  function (req, res) {
    if (req.authInfo) {
      // req.authInfo.message will contain your actual message.
    }
  });