I am using node passport-google-oauth module and trying to redirect the page back to the original path after successful authentication using a session based approached suggested in Custom returnUrl on Node.js Passport's Google strategy. However, I find inside my callback, the redirect info stored in session was always wiped out so I was forced to redirect to a default ('/' in this case).
Here is the logging output from my code snippet. It seems when it's inside the callback, the returnTo got wiped out. Is it a design of the passport-google-oauth? If so, how can one redirect back to the original page after a successful authentication?
// output from
Storing url: /newroom
in /auth/google, returnTo = /newroom
in /auth/google/callback, returnTo = undefined
Storing url: /newroom
in /auth/google, returnTo = /newroom
in /auth/google/callback, returnTo = undefined
// code snippet
var express = require('express'),
[sic]
passport = require('passport'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
cookieParser = require('cookie-parser'),
expressSession = require('express-session'),
bodyParser = require('body-parser');
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: 'http://' + MY_HOST + '/auth/google/callback',
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function() {
console.log('Profile:' + profile);
return done(null, profile);
});
}
));
var auth = function(req, res, next){
if (!req.session.user) {
console.log('Storing url: ' + req.url);
req.session.returnTo = req.url;
res.redirect('/auth/google');
} else if (!userIsValid(req.session.user)) {
// handle invalid user
} else {
next();
}
};
app.get('/auth/google', function(req, res, next) {
console.log("in /auth/google, returnTo = " + req.session.returnTo);
passport.authenticate('google',
{
scope: ['https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email']
}
)(req, res, next)
}
);
app.get('/auth/google/callback', function(req, res, next) {
console.log("in /auth/google/callback, returnTo = " + req.session.returnTo);
passport.authenticate('google', function(err, user, info) {
console.log("in /auth/google/callback callback");
if (err || !user) {
res.redirect('/auth/google');
} else {
var returnTo = req.session.returnTo ? req.session.returnTo : '/';
delete req.session.returnTo;
console.log('Redirecting to: ' + returnTo);
req.session.user = user;
res.redirect(returnTo);
}
})(req, res, next);
});
I use
res.redirect(req.headers.referer);
but problem is sometimes it works sometimes it doesn't as if the user will be first time logging through facebook, facebook will first display the permission dialog which overwrites the referer header var but if user has already granted permission to your app he/she will be redrected back to the url from wherever they are coming.
SBE - Sorry for Bad English ;)