Google API refresh tokens not honoring 'incremental scope' request - google-api

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.

Related

Limits when accessing Google APIs using Service Account vs OAuth

My current application access one of the Google APIs using "3-legs" OAuth 2.0. User authorizes the app on Google consent screen, then the app requests API on behalf of the user and shows him some fancy data loaded from API. Everyday my application loads and transforms data from this API, so when the user comes next time, he sees the most relevant and actual data.
Everything works fine on the start, but as time goes, I faced two problems:
1. Query limits.
2. Token lifetime.
My question is dedicated to the second one, that I refer as "token lifetime". After some amount of time, the access token expires, and when user comes back to the app, our app obliged to send him to consent screen again. Moreover, all the time while access token has been in expired state, my app cannot load relevant data for user.
How can I solve this problem? How to continue lifetime of access/refresh tokens? Would Service account help? Would Service account work for Google Search Console API for every user, or should the user be a G Suite user inside my domain or what?
These questions are completely unclear from the official documentation here and from the Search Console API documentation.
If you have past experience with Google's APIs, please help me!
Thank you
When you use OAuth with user-consent, you do not need to prompt the user for consent repeatedly.
[a] If your usecase is entirely online and you want to be able to request a token each time the user visits your app, use the Google Sign In library or see this documentation for client-side apps.
[b] If your usecase is that you want to be able to obtain access tokens even when the user is not present, then you need to request an authorization code and store your refresh token. Your refresh tokens are longer-lived tokens and can be exchanged periodically for access tokens.

Handle Google api calendar removed access

I am using this googleapis nodejs client for calendar, and everything works perfect except that if I remove access from google account security settings,
calendar is still connected. Is there any method to check for removed access from google account? How to handle those cases?
When a user runs your application the first time they are presented with a consent form. Which asks them to grant permission for your application to access their Google calendar data. From this point on when ever your application runs the user may have to login again but they will not have to grant your application permission. If you have a refresh token you will be able to use that when ever you like to request a new access token. the access token will be valid for one hour.
Now if you request a new access Token as stated its valid for one hour. This is true even if the user goes to Google Account security for their account and removes the consent for an application access their data.
Your still going to be able to access their data while any access tokens you have currently are valid. If the user tries to use your application again they will have to consent permission. If you try to use the refresh token it will no longer work.
Access tokens work for one hour they are not reauthorized during that time its assumed that they are valid. (This may in fact depend upon the scope and API in question and how googles policy server works.)
access token are designed to be self contained permission systems. As long as you have an access token for the correct scope most apis assume that you have access. However in the event this method is accessing critical data then they may have a policy server setup. This server could be doing an extra check on an access token to ensure that the user still has access even though they have a valid access token. However doing this can be very time consuming and resource heavy as reevaluating every call to ensure that the user still has access. It kind of defeats the purpose of having access tokens that are valid for an hour in the first place.

GAPI integration between frontend and backend

I have a single page application with some user-related calendars. The task is to write integration with the google calendar. A user should be able to click on 'integrate with google calendar', select his google account, give read+write access to the calendar, and then the application should be able to do a number of things within the user google calendar like creating a new calendar and sync all events inside it with the application data.
I started with this example, https://developers.google.com/calendar/quickstart/js
It works, but as I understand it's for online front end work only. Is it possible to retrieve authentication from this front end and send it to the back end? I want back end to operate server-to-server mode, while the user is offline.
I have checked the other, back end gapi integrations, but they do not look so cool, there're some redirects. I want to keep everything inside a single page with ajax and popups.
In order to access a users data when the user is off line you need something called offline access. When you authecate the user you will need to request offline access then the server will return to you a refresh token.
A refresh token is long lived you will be able to use your refresh token at anytime to request a new access token which will allow you to access the users data.
You cant use offline access with JavaScript you will need to use a server sided language like say node.js, php, phython .... you will not be able to use gapi

actions-on-google implicit flow and access_token change?

I have developed a Google Action for Assistant (with Api.ai). I have to use a Sign-in method because my app use a website where the user have to sign-in and make something.
In the action console I setup account linking with IMPLICIT method and under AUTHORIZATION URL I inserted my url for the login. It's works.
When I speak for the first time (for testing) to my Google Home, on my smartphone appears the notification for account linking... perfect. My website create a token and record it and every time after my webhook will call with the same access_token. Perfect.
Two questions
This access_token is linked to my google-account forever or google may change it?
How can I disable this account-linking and reset my google-action? I want to re-link my assistant with new access_token. I try to return a http 401 from my webhook but it's not work.
The access token is just a piece of string so Google cannot change that exact one. It might have a lifetime.
I am pretty sure Google has an endpoint that revokes the access token.

Gettinng user profile information for OAuth2 JWT

I am making an api that accepts social logins from a few services, namely Google.
So far, the mobile app allows the user to log in to google with the OAuth2 flow, and obtains a JWT token. The first time I was able to get the profile info from the token (first name, family name, profile pic, etc...). Now, I doesn't contain all of the fields I need.
I remember reading somewhere that google will only send all the fields from time to time...
Since I'm in testing, I tend to wipe the user database often and would like to be able to count on the google JWT to re-create the account.
I'd rather use the token than hitting the userInfo API. Especially since the JWT is technically secure.
So, is there any sure way to get all of the user profile info in the id_token from the google API?
Check the 'scopes' that you define when logging in with Google. Each scope has a type of data that it returns back to the user. Be sure that you're using scope: 'profile'" when initializing the Google login. If additional scopes are necessary, use add them to the request as shown in the link below.
https://developers.google.com/identity/sign-in/web/incremental-auth
I was using an older endpoint, changed to https://accounts.google.com/o/oauth2/v2/auth and everything is ok!

Resources