passport
passport copied to clipboard
passport.authorize() clearing req.user with multiple strategies
I have been trying to wrap my head around this issue for a while. from what I have been reading passport.authorize() shouldn't clear current session. Strategies
exports.SteamStrategy = new SteamStrategy(config.steam, (req, identifier, profile, done) => {
return done(null, profile);
});
exports.OAuth2Strategy = new OAuth2Strategy(config.oauth2, (req, accessToken, refreshToken, params, profile, done) => {
console.log(req.user); // undefined (when authenticated with steam)
return done(null, profile);
});
Routes
// -- steam auth routes
router.get('/steam', passport.authenticate('steam', { failureRedirect: '/' }), (req, res) => {
res.redirect('/');
});
router.get('/steam/return', fixurl, passport.authenticate('steam', { failureRedirect: '/' }), (req, res) => {
res.redirect('/')
});
// wordpress auth routes
router.get('/wordpress',passport.authorize('oauth2'), (req, res) => {
res.redirect('/');
});
router.get('/wordpress/callback',passport.authenticate('oauth2', { failureRedirect: '/' }), (req, res) => {
res.redirect('/');
});
req.user returns the right data on the steam strategy, but returns undefined on the oauth2 strategy,
https://github.com/jaredhanson/passport/issues/81
this is where I got the information to user authorize
not authenticate. any confirmation if this is an issue. or just me being dumb.
I can confirm. I have the same issue with Passport-twitter
Edit For anyone facing the same issue, I have solved it by attaching request params to the request's session. (hacky)
router.get('/connect/twitter', (req, res, next) => {
const { localUrl } = req.query;
Object.assign(req.session, {"calledFromUrl": localUrl})
const authenticator = passport.authorize("twitter");
authenticator(req, res, next);
});
router.get('/connect/twitter/callback/', (req, res, next) => {
const localUrl = typeof (req.session as any).calledFromUrl === "string" ? (req.session as any).calledFromUrl : undefined;
passport.authorize('twitter', (reqest, response) => {
try {
if (localUrl && typeof localUrl === 'string') {
return res.redirect(localUrl)
}
} catch {
// just redirect normally below
}
res.redirect('/')
})(req, res, next);
}
);
Also looking for a solution for this - connecting multiple services is essential for a lot of sites and not being able to do this with Passport is a big bummer.
EDIT:
Fixed my issue by setting express-session
's cookie
's property sameSite
to 'lax'
.
...
app.use(
expressSession({
cookie: {
sameSite: 'lax',
httpOnly: true,
maxAge: 7 * 24 * 60 * 60 * 1000
},
...
I can confirm the issue when using any OAuth2 strategy with .authorize() it does not matter if you use Facebook, Twitter or OAuth2 for any other service I tried, in the callback of the strategy - req.user is always empty.
I ran into the same problem, it's a bit of a hacky solution but I got around it by using req.session?.passport?.user and deserializing the user manually instead of using req.user in the callback.
I can confirm the issue when using any OAuth2 strategy with .authorize() it does not matter if you use Facebook, Twitter or OAuth2 for any other service I tried, in the callback of the strategy - req.user is always empty.
Pls how did you solve this?