I am trying to return a refreshToken using the passport module of node.js.
However I am using the code below and I am unable to log any refresh token but the access token works fine.
Is there any way to specify the access-type offline for this module to hopefully return this?
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://myurl/auth/callback"
},
function(accessToken, refreshToken, profile, done) {
console.log(refreshToken);
process.nextTick(function () {
return done(null, [{token:accessToken}, {rToken:refreshToken}, {profile:profile}]);
});
}
));
This returns the refreshToken as undefined.
Any help would be greatly appreciated.
This was solved with this link:
https://github.com/jaredhanson/passport/issues/42
specifically:
passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'],
accessType: 'offline', approvalPrompt: 'force' });
Jared Hanson - bless you.
All you need is accessType: 'offline'
and you'll get the refreshToken on first login.
You don't need approvalPrompt
or prompt
in the request.
Note this only works on first login if you don't capture and save the refreshToken and associate it with a user account on first login you can't easily get it again.
If you didn't capture it the first time someone logs in you have two options:
If a user logs in and you don't have a refreshToken for them, you can immediately forceably log them out and tell them to go to https://myaccount.google.com/permissions and revoke access to your application then just sign in again.
When they sign in again they will get the same prompt for access they got on first login and you will get the refreshToken on that first new login. Just be sure to have a method in your callback in Passport to save the refreshToken to their user profile in your database.
You can then use the refreshToken to request a rotating accessToken whenever you need to call an a Google API.
You could also add both accessType: 'offline'
and prompt: 'consent'
options, but this is probably not what you want in a web based application.
Using these will prompt every user to approve access to your app every time they sign in. Despite the name, approvalPrompt does not enforce this, at least not in the current version of the API (judging by the number of people mentioning it and how often oAuth APIs change it's entirely possible this behaviour used to be different).
This isn't a great approach for web based apps as it's not a great user experience but might be useful for debugging.