percolatestudio / meteor-google-api

A simple API encapsulating some common patterns regarding Google's APIs
https://atmospherejs.com/percolate/google-api
MIT License
48 stars 30 forks source link

Refresh token not found. [500] #6

Closed deanrad closed 9 years ago

deanrad commented 9 years ago

Hi - consistently, if I leave an app idle long enough, I'll reach a situation where there is still a Meteor.user() (and related accesstoken published to the browser), but the moment I make a request, I'll get the Refresh token not found. [500] message, originating from q.js.

If I logout/log back in, I'll be OK, but I thought this library was supposed to manage the refresh token as well.

My users publish function is publishing all fields with:

  Meteor.publish('userData', function () {
    return Meteor.users.find({_id: this.userId},
    {fields: {'services': 1}});
  });

Thanks in advance

ghjunior commented 9 years ago

Have you wiped the database since first granting Google access to your app? The refresh token is only sent from Google the first time around (when you authenticate an app), so if you've cleared the DB since previously authorised users might not have it stored in Mongo.

I was running into a similar situation, so I de-authorised my Meteor app through my users Google Account Settings, logged in again, and since then haven't run into issues.

ghjunior commented 9 years ago

Or I think passing forceApprovalPrompt will get you a new refresh token: http://docs.meteor.com/#/full/meteor_loginwithexternalservice

Ideally this would only be used if the user does indeed no longer have a refresh token: http://www.riskcompletefailure.com/2013/12/are-you-using-approvalpromptforce.html

g33kidd commented 9 years ago

I had the same issue and adding forceApprovalPrompt gave me the refresh token and I did not have any further problems.

tmeasday commented 9 years ago

Did you figure this one out @chicagogrooves ? I've seen this problem before as @ghjunior describes it.

eldog commented 9 years ago

I have tried forceApprovalPrompt: true and am still seeing Refresh token not found errors after around an hour of being logged in. Will try de-authorising the app.

eldog commented 9 years ago

Nope de-authorising/re-authorising did not seem to work. Still getting error after ~1hour.

eldog commented 9 years ago

I appear to not have a refresh token in my user profile (calling Meteor.call('exchangeRefreshToken') states this). Could this be because I already had a user account using a Google login before I added the Google Api bits? Going to try removing the user from my app and signing up again.

eldog commented 9 years ago

Turns out that I needed requestOfflineToken: true to be in my options for google to hand back a refresh token as stated in https://developers.google.com/accounts/docs/OAuth2WebServer (I think it makes meteor add access_type=offline to the authorization code request).

My login code now looks something like

var options = {
  requestPermissions: [
    'https://www.googleapis.com/auth/userinfo.profile',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/drive.readonly'
  ],
  requestOfflineToken: true, 
  forceApprovalPrompt: true
};

Meteor.loginWithGoogle(options);

Yet to see if this still triggers the refresh token problem (have to wait an hour or so), but at least there is a token for refreshing now.

g33kidd commented 9 years ago

@eldog This worked for me as well, no problems since having both of those options added. Hopefully this works for anyone else too.

deanrad commented 9 years ago

Yup, these two work like a charm :+1:

 requestOfflineToken: true, 
  forceApprovalPrompt: true
Zane-XY commented 9 years ago

This is helpful, for me, just set 'requestOfflineToken: true' solves the problem.

BetoFrega commented 7 years ago

Here is a (not so short) TLDR; for whoever finds this thread on the attempt to fix this issue:

Should you choose to force the oAuth prompt to show on every login, the code will look something like this:

var options = {
  requestPermissions: [
    'https://www.googleapis.com/auth/userinfo.profile',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/drive.readonly'
  ],
  requestOfflineToken: true, 
  forceApprovalPrompt: true
};

Meteor.loginWithGoogle(options);

or like this if you are using Accounts.ui.config:


Accounts.ui.config({
  requestPermissions: {
    google: [
    'https://www.googleapis.com/auth/userinfo.profile',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/drive.readonly'
  ],
  },
  requestOfflineToken: {
    google: true,
  },
  forceApprovalPrompt: {
    google: true,
  }
});