Our app uses several different Google APIs. The app requests offline access for Google Search Console And Google Analytics.
Every now and then the grants given by users are revoked. Several users' grants are revoked, not at the same time, but in a timespan of a couple of days.
I've checked all the usual suspects, but nothing matches. Take my own account for example. I hadn't logged in for a week but all of a sudden my grants had been revoked. I verified that they were revoked in my Google account. So after a week of working, making offline requests, all the grants were revoked, except the basic one.
I'm using the Google php api package, Attaching the access token object to every request.
$this->client = new \Google_Client();
$this->client->setAuthConfig(env("GOOGLE_CLIENT_SECRET_JSON_PATH"));
$this->analyticsService = new \Google_Service_Analytics($this->client);
$this->client->setAccessToken($user->google_access_token_object);
I'm also also setting a callback for the request.
$client->setTokenCallback(function($cacheKey, $accessToken) use ($user, $client) {
$cacheEntry = $client->getCache()->getItem($cacheKey)->get();
$googleAccessTokenObject = json_decode($user->google_access_token_object, true);
$googleAccessTokenObject["access_token"] = $cacheEntry["access_token"];
$googleAccessTokenObject["expires_in"] = $cacheEntry["expires_in"];
$googleAccessTokenObject["scope"] = $cacheEntry["scope"];
$googleAccessTokenObject["token_type"] = $cacheEntry["token_type"];
$googleAccessTokenObject["id_token"] = $cacheEntry["id_token"];
$googleAccessTokenObject["created"] = time();
if(!empty($cacheEntry["refresh_token"])) {
$googleAccessTokenObject["refresh_token"] = $cacheEntry["refresh_token"];
}
$user->google_access_token_object = json_encode($googleAccessTokenObject);
$user->save();
});
This works without problems for weeks, but then it's like Google decides to revoke every extra grant given to the application.
None of the points brought up in this article are valid for us:
https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35
Since more than one account is affected during a timespan of a couple of days (this has happened multiple times) it doesn't seem to be an account based issue, but rather an application level issue.
The app in Google developer console has the "Publishing status" set to testing. I haven't found any info claiming that would be an issue though.
There are serval reasons why a refresh token will expire. The most common one these days is
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
Actually they have the consent revoked after seven days which basically causes all refresh tokens to expire.
So the solution is to set your project to production, No this does not mean you need to verify it that is a separate setting.
Once your project is set to production you refresh tokens will stop expiring.
Related
I've been using the Google API to update one of my Chrome plugins on a weekly basis. This has now happened 3 or 4 times now: The refresh token I acquire will work properly for up to two weeks (only being used once per week), then the third week, returning an error saying that my token has been expired or revoked.
Given that I'm the only user with access to these tokens, I know that there isn't any spamming, and I know that nobody would be authorized to revoke the tokens on my end.
Please advise. Thanks!
There are serval reasons why an access token can expire.
the user revoked your access.
depending upon which scope you are using if the user changes their password it can revoke all out standing refresh tokens (mostly gmail I think)
If your application is still in testing phase refresh tokens only last for two weeks you will need to move your application to production and go though the verification process. (this appears to have been a stealth change i can find no information on it)
you can have a max of 50 outstanding refresh tokens for a users account, if the user is logging in multiple times and you get a new refresh token each time make sure you are always using the newest.
Your application should always be set to request access of the user again in the event that the refresh token has expired.
I have recently worked with Google Ads API and Shopping Content API and experienced detailed behaviour of API authentication mechanics.
What i can tell for sure regarding authentication is the the following:
An Access-Token always have a life time of 60min. and then expires
An refresh-Token makes it easier to obtain a new Access-Token, since
no additional verification is needed
The lifetime of a Refresh-Token varies
it can be a 6 month or more (when the related application publishing status is released)
or just 1 week (when the related application publishing status is testing)
You can find detailed information regarding Token Expiration on the Google API Documentation https://developers.google.com/identity/protocols/oauth2#expiration
Also information regarding publishing status of your API application Token has expired or revoked - Google Ads
We have an app that over time obtained and worked with Google OAuth2 tokens. Now it got the 'Unverified app' status allowing < 100 installs. We know we have < 100 users with active access tokens but the Google OAuth team tells us there are > 100 outstanding access tokens.
How can we revoke those unused/orphaned tokens that our app does not track anymore? We can't issue the 'revoke' requests because we don't know those tokens. Is there a way for an app to list all outstanding oauth2 tokens or to revoke all its tokens?
Thank you
Such an access token has a lifetime of about an hour - you probably mean app authorizations aka "Third-party sites & apps with access to your account", which last until being revoked by the user. So generally there's not much to do about it, unless suggesting the users to revoke the access manually. Changing the name of the package might be the only option available on your side, to get rid of them.
Authorized users
First off you don't have unused/orphaned tokens not really. What you have is users who have granted your application permission to access their data. There is no way for you to see exactly who these users are. There is no way to remove their granted consent unless you have refresh tokens for each of them saved in your system some place. If you do you could call a revoke on all of those refresh tokens and it should / might release a few of your 100 installs. This is just a guess i have never tried it.
curl -H "Content-type:application/x-www-form-urlencoded" \
https://accounts.google.com/o/oauth2/revoke?token={token}
application verification
The issue you are having is that your application is unverified. Google has placed a limit of 100 installs on unverified applications during the development process this way you can test your application before it goes live. What you should do is go to Google developer console and request that your application be Verified.
An unverified app is an app or Apps Script that requests a sensitive or restricted OAuth scope, but hasn't gone through the Google verification process. Users of unverified apps or your test builds might get warnings based on the OAuth scopes you're using. This is to protect users and their data from deceptive apps.
Once your application has been verified you will no longer be under the 100 installs limitation. You need to go though the verification process.
Use of this API scope will be restricted until it is approved
our consent screen is being verified. This may take up to several days. Your last approved consent screen is still in use.
Before your users authenticate, this consent screen will allow them to choose whether they want to grant access to their private data, as well as give them a link to your terms of service and privacy policy. This page configures the consent screen for all applications in this project.
Verification status
Being verified (Last approved consent screen is still in use)
Because you've added a sensitive scope, your consent screen requires verification by Google before it's published.
How long verification takes depends greatly upon the application, and the scopes it uses. I have seen anything from a few days to six weeks+ and Google asking for a video of your application running.
This is why its good to start the process while you are still in development developers with access to the project in google developer console should still be able to use your application while you are in the verification process.
We have a webapp that integrates with a number of Google APIs (calendars, contacts, drive). We have an integrations panel where the user can selectively check on each integration. When a new integration is enabled we save the new refresh token Google returns and flag the old one as inactive. Great so far.
The problem is when we request a new scope (incremental), Google seems to correctly add the scope to the User (if we check granted scopes from the frontend it shows the correct list), but if we check scopes from the access token it will only list profile and whatever we just requested.
So if someone enables Calendar, that refresh token will have 'profile' and 'calendar', but if they then enable Drive, the new refresh token will have only 'profile' and 'drive', not 'calendar'. This is especially problematic for our Drive worker, as it will generate a lovely slew of errors as it tries to build out a User's Drive with a valid refresh token but invalid scopes.
On the backend, I'm using the setIncludeGrantedScopes(true) method before I cash in the code, and as far as I know the front end is doing what it should (it does seem to have the expected scopes), but the refresh token is not inclusive.
Tips/tricks/gotchas/etc?
So, it turns out that this was a fairly simple solution, but was documented in only one place: when the front-end requests an additional scope, it must also send up all current scopes.
Failing to do this will cause the returned refresh token to represent only the scopes included in the grant request, while the app will incrementally gain scopes as expected.
I am considering developing an application for the Apps for Business Marketplace. I see that new rules takes affect on November 19th. Referring to the new documentation (https://developers.google.com/apps-marketplace/) I do not see that any SSO requirement exists. There is allot of talk about migrating to new sign on methods, but I see no mention of sign on requirements.
What are the sign on requirements as of November 19th?
If SSO continues to be required or if I publish before Nov. 19th, my application requires security token from my API, in order to carry out API exchanges. To get this token a user/pass exchange is required one time. They would never need to enter a user/pass for my app after that. Will a one time exchange for the security token be denied under a SSO requirement?
For example the statement regarding SSO that an app cannot do is:
The end user should not be required to enter a username and password when invoking an application from within Google Apps. (https://developers.google.com/google-apps/marketplace/sso)
In my case it would not be required for the user to enter every time, just on the initial creation of the account. After that I would retain the token from my site, encrypted with the Installed App.
Would my app be denied for requiring this one time exchange under the SSO policy?
Mark
You will have to use SSO (or should if at all possible) -- see this part of the documentation: Besides, that is a better practice and should make your users feel more trust for your application.
From what I gather (note that I'm building my first marketplace app) you should not prompt users to enter username/password on your site. I am creating user record & storing token behind the scenes. So the user sees Google authorization screen, agrees to let my app use some data, accepts and sign-in right away without any prompt to create an account. After this, user will not be prompted in the future because I have their google id linked to a user record.
From their site - https://developers.google.com/google-apps/marketplace/sso#user_experience
As long as you don't have any intermediate screen, your app should be approved.