0

I'm having trouble understanding whats going on with the custom callback for Passport.js. I don't understand the (req, res, next) at the end. Should we have these values from closure?

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); //<=== What is the purpose of this?
});
Elliot
  • 1,893
  • 4
  • 17
  • 35
  • It's a self-invoking function. It's calling itself passing the req, res and next as params. https://jsfiddle.net/ccestd3o/ – yBrodsky Sep 26 '16 at 20:33

2 Answers2

1

passport.authenticate() is a middleware. Briefly, a middleware is a function that modifies the request then passes it along to the next request handler. Request handlers in express are functions that take (req, res, next) as arguments. passport.authenticate, then, is a function which returns a middleware, which takes (req, res, next) as arguments.

Generally, it will be used like this:

app.get('/login', passport.authenticate());

whereby passport.authenticate() will modify the request, make sure the user is authenticated, then pass it along to the next handler.

In this case, we want passport.authenticate to do a little more, so we replace:

app.get('/login', passport.authenticate());

with the equivalent:

app.get('/login', function (req, res, next) {
  passport.authenticate()(req, res, next)
});

and then more logic is added into the passport.authenticate constructor.

Community
  • 1
  • 1
000
  • 26,951
  • 10
  • 71
  • 101
  • 1
    Ohh that makes sense. Normally when used as middleware it is invoked with the req, res, next arguments. Since we aren't using it as normal middleware in this instance, we must pass those values in ourselves. – Elliot Sep 26 '16 at 20:38
0

yes the (req, res, next) passes those values into your passport.authenticate function from the router context. If i were you i would also look into middleware for your router (express?) - its an easy way to add authentication to your routes rather than the granular way you are doing it here (would have to add that passport.auth into every route you wanted to authenticate).

steveinatorx
  • 705
  • 9
  • 22