Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an additional parameter to passport.authenticate

(I already do fbStrategy.passReqToCallback = true ) I am riffing off https://scotch.io/tutorials/easy-node-authentication-linking-all-accounts-together but want to use this social authentication service for multiple apps, ex: the one that controls the heating system, the one that turns on the sprinklers etc.

Basically if one of these apps checks with the server and doesn't have a correct token it get redirected to this social authentication service (social-auth). When the user presses on of the social login buttons it grabs the parameter of what app its arriving from and adds it as a parameter for /auth/facebook/:appid

    // send to facebook to do the authentication
    app.get('/auth/facebook/:appId', function(req,res,next){
        passport.authenticate(
            'facebook', { scope : 'email' }
        )(req,res,next);
    });

req of req,res,next is the serialized user record. At this point social-auth doesn't know who the user is.

fbStrategy.passReqToCallback = true;  
passport.use(new FacebookStrategy(fbStrategy,
    function(req, token, refreshToken, profile, done) {
        var email = (profile.emails[0].value || '').toLowerCase()     
        process.nextTick(function() {...

Once authorization is complete I want to redirect back to the calling app and I need the :appId param to ride along so I can go back to the right site.

Now generally it would work if I just made a variable like currentAppId accessible to the various social stategies but If you happened to have multiple people authenticating at the same time then you conceivably have a user return to the wrong app, or some other users app. That's why I need appId to travel as param to passport.authenticate . Where should I be looking to figure out how. Could I wrap passport.authenticate or otherwise modify things?

like image 963
mcktimo Avatar asked Apr 06 '17 21:04

mcktimo


People also ask

Can passport use multiple strategies?

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

What does passport authenticate () do?

In this route, passport. authenticate() is middleware which will authenticate the request. By default, when authentication succeeds, the req. user property is set to the authenticated user, a login session is established, and the next function in the stack is called.

Is Passport good for authentication?

Passport is a popular, modular authentication middleware for Node. js applications. With it, authentication can be easily integrated into any Node- and Express-based app. The Passport library provides more than 500 authentication mechanisms, including OAuth, JWT, and simple username and password based authentication.


2 Answers

You can use the request itself to transfer some additional parameters from and to the strategy function. In the following example the two parameters _toParam and _fromParam are used for this concern.

app.get('/auth/facebook/:appId', function(req,res,next){
    req._toParam = 'Hello';
    passport.authenticate(
        'facebook', { scope : 'email' }
    )(req,res,next);
})


fbStrategy.passReqToCallback = true;  
passport.use(new FacebookStrategy(fbStrategy,
    function(req, token, refreshToken, profile, done) {
        console.log(req._toParam);
        req._fromParam = 'Hello 2';
        var email = (profile.emails[0].value || '').toLowerCase()     
    process.nextTick(function() {...

If you need to store the id for further requests, you could use a map with the socket of the current request as key.

like image 72
Manfred Steiner Avatar answered Oct 12 '22 20:10

Manfred Steiner


In my case, due to the authentication flow, to set up a variable in req was not working.

The second option, set passReqToCallBack: true was giving me many issues, so it was not an option either. More information can be found here.

The solution came to me following the answer that Dhiraj posted in thread above, I did set a single string in the state and I was able to use the string on the callbacks.

login: (req, res, next) => passport.authenticate('google', {
    scope: ['profile', 'email'],
    state: req.query.username
  }, () => next())(req, res, next),

  onSuccess: async(req, res) => {
    console.log(req.query.state)
  },
like image 39
davidrl1000 Avatar answered Oct 12 '22 21:10

davidrl1000