New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't access "expires_in" parameter #23

Closed
maxbrodie opened this Issue Oct 25, 2013 · 6 comments

Comments

Projects
None yet
4 participants
@maxbrodie

maxbrodie commented Oct 25, 2013

Unless I'm missing something, in addition to an access token, a refresh token, and a profile the verify function should also have expires_in as a parameter.

From https://developers.google.com/accounts/docs/OAuth2UserAgent#handlingtheresponse

"Other parameters included in the response include expires_in and token_type. These parameters describe the lifetime of the token in seconds, and the kind of token that is being returned."

@jaredhanson

This comment has been minimized.

Show comment
Hide comment
@jaredhanson

jaredhanson Oct 25, 2013

Owner

There's a 5-argument form of the verify callback, like this:

function(accessToken, refreshToken, params, profile, done) {
  console.log(params.expires_in);
  // save tokens and expiry time
}

params contains all the parameters in the OAuth 2.0 response, including the expiration time.

As to your SO question, Passport doesn't use the access token or refresh token in any way, except to fetch the user profile. If you want to use the refresh token to obtain a new access token, you'll need to do that in your backend processes.

Owner

jaredhanson commented Oct 25, 2013

There's a 5-argument form of the verify callback, like this:

function(accessToken, refreshToken, params, profile, done) {
  console.log(params.expires_in);
  // save tokens and expiry time
}

params contains all the parameters in the OAuth 2.0 response, including the expiration time.

As to your SO question, Passport doesn't use the access token or refresh token in any way, except to fetch the user profile. If you want to use the refresh token to obtain a new access token, you'll need to do that in your backend processes.

@maxbrodie

This comment has been minimized.

Show comment
Hide comment
@maxbrodie

maxbrodie Oct 25, 2013

Thanks Jared! Just made my friday evening.

maxbrodie commented Oct 25, 2013

Thanks Jared! Just made my friday evening.

@Slotos Slotos referenced this issue Oct 6, 2014

Closed

refresh_token flow #10

@josdejong

This comment has been minimized.

Show comment
Hide comment
@josdejong

josdejong Oct 8, 2014

I'm trying to get a refreshToken back, but so without luck. I've configured both accessType and approvalPromt, still the parameter refreshToken of the verify function remains undefined. The params object contains parameters access_token, token_type, expires_in, and id_token.

passport.use(new GoogleStrategy({
      clientID: GOOGLE_CLIENT_ID,
      clientSecret: GOOGLE_CLIENT_SECRET,
      callbackURL: CALLBACK_URL,
      scope: ['profile', 'email', 'https://www.googleapis.com/auth/calendar'],
      accessType: 'offline',
      approvalPrompt: 'force'
    },
    function(accessToken, refreshToken, params, profile, done) {
      // PROBLEM: refreshToken is undefined
      profile.auth = {
        accessToken: accessToken,
        refreshToken: refreshToken,
        params: params
      };
      return done(null, profile);
    }
));

What am I overlooking?

josdejong commented Oct 8, 2014

I'm trying to get a refreshToken back, but so without luck. I've configured both accessType and approvalPromt, still the parameter refreshToken of the verify function remains undefined. The params object contains parameters access_token, token_type, expires_in, and id_token.

passport.use(new GoogleStrategy({
      clientID: GOOGLE_CLIENT_ID,
      clientSecret: GOOGLE_CLIENT_SECRET,
      callbackURL: CALLBACK_URL,
      scope: ['profile', 'email', 'https://www.googleapis.com/auth/calendar'],
      accessType: 'offline',
      approvalPrompt: 'force'
    },
    function(accessToken, refreshToken, params, profile, done) {
      // PROBLEM: refreshToken is undefined
      profile.auth = {
        accessToken: accessToken,
        refreshToken: refreshToken,
        params: params
      };
      return done(null, profile);
    }
));

What am I overlooking?

@Mickael-van-der-Beek

This comment has been minimized.

Show comment
Hide comment
@Mickael-van-der-Beek

Mickael-van-der-Beek Oct 13, 2014

👍
I'm getting the same issue.

Mickael-van-der-Beek commented Oct 13, 2014

👍
I'm getting the same issue.

@josdejong

This comment has been minimized.

Show comment
Hide comment
@josdejong

josdejong Oct 16, 2014

I figured out what I did wrong: instead of configuring the accessType and approvalPrompt in new GoogleStrategy({...}), you have to configure them in passport.authenticate('google', { ... }));. See also #28.

Here is a full example that gives a refreshToken:

var express  = require('express');
var cookieParser  = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var argv = require('yargs').argv;

var PORT = 8082;
var GOOGLE_CLIENT_ID = argv.GOOGLE_CLIENT_ID;
var GOOGLE_CLIENT_SECRET = argv.GOOGLE_CLIENT_SECRET;

var app = express();
app.use(cookieParser());
app.use(session({
  secret: 'keyboard cat',
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.listen(PORT);
console.log('Server listening at http://localhost:' + PORT);

passport.use(new GoogleStrategy({
      clientID: GOOGLE_CLIENT_ID,
      clientSecret: GOOGLE_CLIENT_SECRET,
      callbackURL: 'http://localhost:' + PORT + '/auth/callback',
      scope: ['profile', 'email']
    },
    function(accessToken, refreshToken, params, profile, done) {
      console.log('accessToken', accessToken);
      console.log('refreshToken', refreshToken);
      console.log('params', params);
      console.log('profile', profile);
      return done(null, profile);
    }
));

app.get('/', function (req, res) {
  if (req.session.user) {
    res.send('<html><body><pre>' +
        JSON.stringify(req.session.user._json, null, 2) +
        '</pre></body></html>')
  }
  else {
    res.send('<html><body><a href="/auth">Login</a></body></html>')
  }
});

app.get('/auth',
    passport.authenticate('google', {
      session: false,
      accessType: 'offline',
      approvalPrompt: 'force'
    }));

app.get('/auth/callback',
    passport.authenticate('google', { session: false, failureRedirect: '/' }),
    function(req, res) {
      req.session.user = req.user;
      res.redirect('/');
    });

josdejong commented Oct 16, 2014

I figured out what I did wrong: instead of configuring the accessType and approvalPrompt in new GoogleStrategy({...}), you have to configure them in passport.authenticate('google', { ... }));. See also #28.

Here is a full example that gives a refreshToken:

var express  = require('express');
var cookieParser  = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var argv = require('yargs').argv;

var PORT = 8082;
var GOOGLE_CLIENT_ID = argv.GOOGLE_CLIENT_ID;
var GOOGLE_CLIENT_SECRET = argv.GOOGLE_CLIENT_SECRET;

var app = express();
app.use(cookieParser());
app.use(session({
  secret: 'keyboard cat',
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.listen(PORT);
console.log('Server listening at http://localhost:' + PORT);

passport.use(new GoogleStrategy({
      clientID: GOOGLE_CLIENT_ID,
      clientSecret: GOOGLE_CLIENT_SECRET,
      callbackURL: 'http://localhost:' + PORT + '/auth/callback',
      scope: ['profile', 'email']
    },
    function(accessToken, refreshToken, params, profile, done) {
      console.log('accessToken', accessToken);
      console.log('refreshToken', refreshToken);
      console.log('params', params);
      console.log('profile', profile);
      return done(null, profile);
    }
));

app.get('/', function (req, res) {
  if (req.session.user) {
    res.send('<html><body><pre>' +
        JSON.stringify(req.session.user._json, null, 2) +
        '</pre></body></html>')
  }
  else {
    res.send('<html><body><a href="/auth">Login</a></body></html>')
  }
});

app.get('/auth',
    passport.authenticate('google', {
      session: false,
      accessType: 'offline',
      approvalPrompt: 'force'
    }));

app.get('/auth/callback',
    passport.authenticate('google', { session: false, failureRedirect: '/' }),
    function(req, res) {
      req.session.user = req.user;
      res.redirect('/');
    });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment