Enabling Additional Data in Passport Middleware Using Express

The user navigates to my web route from another application with a link that was generated in this form: /auth/steam/:id/:token

where :id

and are :token

not required for this Passport middleware. They are just parameters that I want to track.

When the user is successfully authenticated, I want to access these values ​​from the original web request before /auth/steam/

. My routes currently look like this:

this.app.get('/auth/steam/:id/:token', passport.authenticate('steam'), () => {

});

this.app.get('/auth/steam/return', passport.authenticate('steam', { failureRedirect: '/login' }), (req, res) => {
  // Would like access to id and token here

  res.render('index');
});

      

Is it possible to store the data along with the request in the reverse route, etc., where I noticed I want to use the values? I was thinking about using a session but was hoping to avoid it.

Thank!

Update: I tried to use express-session

to add data to session like this:

this.app.get('/auth/steam/:id/:token', passport.authenticate('steam'), (res, req) => {
  req.session.discord_id = req.params.id;
  req.session.token = req.params.token;
  this.logger.info('Redirecting to Steam');
});

this.app.get('/auth/steam/return', passport.authenticate('steam', { failureRedirect: '/login' }), (req, res) => {
  console.log('session', req.session.token);
  res.redirect('/');
});

      

The problem is that when returning to the /auth/steam/return

session, it was updated with a new session from an OpenID request. My data no longer exists.

+3


source to share


3 answers


You obviously don't need a custom login strategy as Steam has its own OpenID strategy ( https://github.com/liamcurry/passport-steam ).

Using sessions is probably the path you've tried, and I believe you can make a couple of tweaks to your route '/auth/steam/:id/:token'

to make it work. I've provided an example that switches the order of your call passport.authenticate('steam')

with another callback (which will never be available since pass.authenticate () redirects you), uses the express middleware feature, next()

and includes req.session.save()

that actually saves the session back to the store. which you are using (documentation at https://github.com/expressjs/session ). Let me know if you use the following as your new route does not preserve the discord_id and session token properties when you return to'/auth/steam/return'



this.app.get('/auth/steam/:id/:token', (req, res, next) => {
  req.session.discord_id = req.params.id;
  req.session.token = req.params.token;
  this.logger.info('Redirecting to Steam');
  req.session.save(next);
}, passport.authenticate('steam'));

      

+1


source


If I understand your question correctly, you need to implement a custom login strategy. This can be done by changing your strategy to get the req parameters inside the strategy callback:

passport.use('steam',
            new LocalStrategy({
            usernameField: 'email',
            passwordField: 'password',
            passReqToCallback: true 
        },
        function(req, email, password, done) {
            //Do your authentication here
            /**Some Authentication Logic **/
              //Get Parameters from the request object...
                 var id = req.params.id;
                 var token = req.params.token
                 var info = {id:id,token:token};
                 return done(error,user,info);
            });

        }));

      

And then you can access the information object in the request. Below is an example of the function you used:



function loginUser(req, res, next) {
    passport.authenticate('steam', function(err, user, info) { 
        //custom callback requires you to login
        // your custom variables are in the info object       
        req.login(user, loginErr => {
            if (!loginErr) {
                return res.status(200).json({
                    success: true,
                    err: null,
                    message: 'Logged in correctly!',
                    id: info.id,
                    token: info.token
                });
            } else
                return res.status(401).json({
                    success: false,
                    message: 'Unable to login!'
                });
        });
    })(req, res, next);
}

      

Again, this can be customized for the functionality you want to implement. If you are using a custom callback, you need to call the req.login function manually, but this gives you a lot more control over the function you are trying to implement.

+1


source


Many people use the express session module for this task.

Once the session is established you can simply do req.session.token = req.params.token;

and then in your other handler retrieve it withreq.session.token

You can also assign properties to the passport instance, but this is a bad idea.

-1


source







All Articles