Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing through URL parameters through Passport OAuth flow

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');  
    }
  }
}
like image 429
kd1978 Avatar asked Mar 10 '23 02:03

kd1978


1 Answers

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!

like image 76
Leandro Rodrigues Avatar answered Apr 26 '23 21:04

Leandro Rodrigues