0

Possibly a silly question, I am trying to work through an example for OAuth and want to understand exactly what is happening before I add to my own code.

Sample is node, express using passport-azure-ad

The route is being defined and a call to passport.authenticate is made.

app.get('/login',
  (req, res, next) => {
      passport.authenticate('azuread-openidconnect', 
      { 
        response: res,
        resourceURL: config.resourceURL,
        failureRedirect: '/' 
      })(req, res, next); // <-- Here is what I am stuck on. 
   },
   (req, res) => {
       log.info('Login was called in the Sample');
       res.redirect('/');
});

I am trying to understand the (req, res, next); that follows directly after the authenticate.

Appreciate any help, or a link to the theory/documentation on this syntax.

Bibberty
  • 4,670
  • 2
  • 8
  • 23
  • `(req, res, next) => {...}` is the function the `(req, res, next)` is where it automatically calls the function with those parameters. This is called a [Self invoking function](https://www.google.com/search?q=javascript+self+invoking+function) – Get Off My Lawn May 29 '19 at 20:46
  • Possible duplicate of [What is the purpose of a self executing function in javascript?](https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript) – Get Off My Lawn May 29 '19 at 20:46
  • @GetOffMyLawn I understand the `(()=>)()` syntax, but this is a method `object.method(params)(params)`. is that the same? – Bibberty May 29 '19 at 20:48

2 Answers2

1

That's because passport.authenticate returns a function (middleware) to handle the request, so you're passing the request to the actual handler here

like this:

function authenticate(someArg) {
    return function (req, res, next) {
        // the handler
    }
}

And this is a simplified version of the example you provided, without the extra explicit pass of the parameters

app.get('/login', passport.authenticate('azuread-openidconnect', { 
    response: res,
    resourceURL: config.resourceURL,
    failureRedirect: '/' 
}), (req, res) => {
    log.info('Login was called in the Sample');
    res.redirect('/');
});
Rami Jarrar
  • 4,523
  • 7
  • 36
  • 52
  • Ok, so authenticate is similar to `Promise` syntax and we are calling it? – Bibberty May 29 '19 at 20:50
  • its different than a Promise, this is called a closure https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures – Rami Jarrar May 29 '19 at 20:51
  • Thanks, the strangest thing is the actual documentation shows it being used as a straight call. But the demo uses above syntax and still works. – Bibberty May 29 '19 at 20:54
  • That's because in the documentation it's passed as an express route handler, so express module will make this extra step/call internally when a request comes in. – Rami Jarrar May 29 '19 at 20:56
  • Yes, that is exactly what I expected Rami. So do you think the Demo author has simply made an error in invoking it? – Bibberty May 29 '19 at 23:54
  • No it's not a mistake, it will work normally, but it's redundant, checkout my update – Rami Jarrar May 30 '19 at 00:01
  • Thanks, I prefer the simplified. I fully understand these are all being called by Express. Was just confused by the way it as used in this instance. Thanks for the help. – Bibberty May 30 '19 at 00:04
0

I think this is just a question of understanding the Javascript syntax for what is called a "lambda" function. Consider the following expression:

(a) => { console.log(a) }

That's a way of writing a function that takes one argument and prints it out. You can put that expression in anyplace you need to specify a function that prints out one argument. This is useful because in Javascript functions can be passed around just like data, and this syntax allows you to define a function right when you need it, without bothering to give it a name.

In your example you are calling app.get with three arguments. The first is the string '/login'. The second is a function that takes 3 arguments, and the function is defined right there in line, to call passport.authenticate, which returns a function, which is called with those 3 arguments. The third is a function that takes 2 arguments, also defined right there in line.

Duncan
  • 507
  • 3
  • 14