I currently have Google OAuth2 implemented in node.js using the excellent Passport framework, but I am finding it difficult to pass through URL parameters in the workflow.
What I'd like to do for example, would be to have a url like /analysis?id=1234
and then to be able to load that specific analysis.
It works once you are already authenticated and the session hasn't expired yet, but it doesn't work yet when you are not already authenticated. I am struggling with passing it through to the callbackURL I think. Any guidance would be appreciated!
Here is what I have thus far (relevant code only)
var session = require('express-session');
var storage = require('node-persist');
var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth2').Strategy;
var GOOGLE_CLIENT_ID = "<google_client_id>"
, GOOGLE_CLIENT_SECRET = "<google_client_secret>",
GOOGLE_CALLBACKURL = "http://localhost:1425/auth/google/callback";
app.use(session({
maxAge: 86400000, // 24 hours
secret: 'no-one-will-find-out',
resave: true,
saveUninitialized: true
}));
var sess;
app.use(passport.initialize());
app.use(passport.session());
storage.initSync();
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: GOOGLE_CALLBACKURL
},
function(accessToken, refreshToken, profile, cb) {
return cb(null, profile);
}
));
passport.serializeUser( function(user, cb) {
cb(null, user);
});
passport.deserializeUser( function(obj, cb) {
cb(null, obj);
});
app.get('/login', function (req, res) {
var id = req.query_id;
if (id) {
var url = '/auth/google?id=' + id;
} else {
var url = '/auth/google';
}
res.render('landing', {url: url, layout: 'landing.hbs'});
});
app.get('/login_error', function (req, res) {
var url = '/auth/google';
res.render('landing', {url: url, error: 'show', layout: 'landing.hbs'});
});
app.get('/analysis', ensureAuthenticated, function (req, res) {
sess = req.session;
var email = res.req.user.email;
var domain = res.req.user._json.domain;
var img = res.req.user._json.image.url;
var id = req.query.id;
console.log(id);
sess.email = encodeURIComponent(email);
sess.domain = encodeURIComponent(domain);
if (domain == 'dropbox.com') {
if (id) {
res.render('index', { email: email, img: img, query: id });
} else {
res.render('index', { email: email, img: img, query: '' });
}
} else {
res.redirect('/login_error');
}
});
app.get('/auth/google', passport.authenticate('google', { scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.profile.emails.read']
}));
app.get('/auth/google/callback',
passport.authenticate('google', {
failureRedirect: '/login_error'
}),
function(req, res) {
var id = req.query.id;
// Successful authentication, redirect home.
if (id) {
res.redirect('/analysis?id=' + id);
} else {
res.redirect('/analysis');
}
}
);
function ensureAuthenticated(req, res, next) {
var id = req.query.id;
sess = req.session;
if (req.isAuthenticated()) {
return next();
} else {
console.log('need to login');
if (id) {
res.redirect('/login?id=' + id);
} else {
res.redirect('/login');
}
}
}
I'm not sure, but I believe google auth won't send you back your 'query string'.
So maybe, you could put your 'id' param in the session:
Set the session here:
app.get('/auth/google', function(req, res, next) {
req.session.analysis_id = req.query.id;
next();
}, passport.authenticate('google', { scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.profile.emails.read']
}));
Retrieve it here:
app.get('/auth/google/callback',
passport.authenticate('google', {
failureRedirect: '/login_error'
}),
function(req, res) {
var id = req.session.analysis_id;
// Successful authentication, redirect home.
if (id) {
res.redirect('/analysis?id=' + id);
} else {
res.redirect('/analysis');
}
}
);
What do you think about it?
Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With