passport.js with multiple authentication providers?
Asked Answered
M

1

66

Using Passport.js is there a way for me to specify multiple authentication providers for the same route?

For example (from passport's guide) can I use local and facebook and twitter strategies on the sample route below?

app.post('/login',
  passport.authenticate('local'), /* how can I add other strategies here? */
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/users/' + req.user.username);
  });
Maxiemaxilla answered 23/12, 2013 at 14:11 Comment(1)
Why do you expect after mixing multiple strategies into one route?Overindulge
G
122

Passport's middleware is built in a way that allows you to use multiple strategies in one passport.authenticate(...) call.

However, it is defined with an OR order. This is, it will only fail if none of the strategies returned success.

This is how you would use it:

app.post('/login',
  passport.authenticate(['local', 'basic', 'passport-google-oauth']), /* this is how */
     function(req, res) {
       // If this function gets called, authentication was successful.
       // `req.user` contains the authenticated user.
       res.redirect('/users/' + req.user.username);
});

In other words, the way to use it, is passing an array containing the name of the strategies you want the user to authenticate with.

Also, dont forget to previously set up the strategies you want to implement.

You can confirm this info in the following github files:

Authenticate using either basic or digest in multi-auth example.

Passport's authenticate.js definition

Ganister answered 23/12, 2013 at 16:3 Comment(9)
How can I tell which authentication strategy eventually used to authenticate the users? I can of course a different endpoint for each strategy, but I am trying to avoid it.Carrageen
@asafam as far as I remember, the req.user holds the info used by the login strategy. Would have to check it out tho.... Most of the info used in the session (after) is kept in the req objectGanister
Thanks @DaniloRamirez. I am using a sessionless approach for my API server. I found the answer to be with the req.info object that can be set with custom data.Carrageen
I cannot figure out how this is useful. Basic Strategy needs to be done every request, at least to work with something like curl. While Local Strategy will keep sessions for a browser. So if I want to have an API that is sessioned for the browser via a login, but BasicAuth with credentials for each request via curl, I don't seem to be able to do it. Is that possible?Cohesive
One thing I'm still missing is how serialize/deserialize is supposed to work, since it's the same for all the strategies. Are we supposed to guarantee that all the strategies are returning the same userModel?Dwan
Same here. I have two user models for my application: user and device. Devices use a token strategy, while users use local. What's the best practice here?Malvinamalvino
@JimBaldwin I guess you can setup different endpoints and specify the logic to select from the two user models via req.users. Maybe userType that would point to user or device modelsGanister
Sorry, I know this is old, but I want the user to decide which strategy they want to use. How does that work out?Bushy
@DaniloRamirez Is there a way also to pass an array of settings for each of the strategies passed?Impoverish

© 2022 - 2024 — McMap. All rights reserved.