Reputation: 408
A user is coming to my web route from another application with a link that was generated in this form: /auth/steam/:id/:token
, where :id
and :token
are not required for this Passport middleware. They are just parameters I want to keep track of.
When the user successfully authenticates, I want to have access to these values from the initial web request to /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 keep data along with the request into the return route, etc. where I noted I want to use the values? I was thinking of using a session but was hoping to avoid that.
Thanks!
Update: I've tried using express-session
to add data to the session like so:
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 when arriving back at /auth/steam/return
, the session has been updated with the new session from the OpenID request. My data no longer is there.
Upvotes: 3
Views: 2614
Reputation: 2455
You obviously don't want a custom login strategy since Steam has it's own OpenID strategy (https://github.com/liamcurry/passport-steam).
Using sessions is probably the way to go as you've tried, and I believe you can make a couple tweaks to your '/auth/steam/:id/:token'
route to make it work. I provided an example that switches the order of your passport.authenticate('steam')
call with your other callback (which would never get to since the passport.authenticate() would redirect you), uses express's middleware next()
function, and includes a req.session.save()
, which actually saves the session back to the store you're using (documentation in https://github.com/expressjs/session). Let me know if using the following as your new route doesn't save the session's discord_id and token properties when you get back 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'));
Upvotes: 4
Reputation: 375
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 info object in the request. Here is an example of the sort of function you would use:
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);
}
Once again, this can be customized to the sort of functionality you are looking to implement. If you use a custom callback, you need to call the req.login function manually, but this gives you a lot more control on the sort of function you are trying to implement.
Upvotes: 2
Reputation: 2161
Many people use express's session module for this task.
Once session is installed you can simply do
req.session.token = req.params.token;
and then in your other handler retrieve it with req.session.token
You can also assign properties to the passport instance, but this is a bad idea.
Upvotes: -1