7

I'm trying implement a photo uploading to Google Drive feature (using the Google Drive API and GIS) into a web app that I'm working on, but can't seem to figure out how to keep a user authenticated for longer than the designated expiry time of the access token (which is 1 hour) without prompting the user or opening a popup.

The sample code provided at https://github.com/googleworkspace/browser-samples/blob/master/drive/quickstart/index.html forces the user to click a "refresh" button to get a new token, but this means I would have to force users to sign in every hour, which isn't ideal (since users are likely going to be using the app for periods longer than an hour at a time).

According to https://developers.google.com/identity/oauth2/web/guides/use-token-model#token_expiration, this appears to be intentional. However, after looking around quite a bit, I found that one could supposedly use a refresh token to generate a new access token that expires after another hour. Assuming you generate a new token every 45 minutes or so (which another Google article actually suggested, but I can't seem to find it now), then you should never have to worry about this re-authentication.

However, I can't figure out how to get a refresh token.

Not receiving Google OAuth refresh token suggests sending access_type=offline as a query parameter, but I'm not using any redirects, and the aforementioned documentation for initTokenClient and requestAccessToken don't make any mention of an access_type parameter.

The closest I've gotten is calling the requestAccessToken method periodically, but this still brings up a popup for the user to sign in again, which is what I'm trying to avoid. Even using requestAccessToken({ prompt: "" }) still brings up this popup window, but it at least logs in without any user input. Is there any way to disable this popup window entirely?

Worst case scenario, I force the user to re-authenticate every hour, but this seems like it would make for a less-than-ideal UX. Any help is appreciated.

simplexshotz
  • 139
  • 12
  • 1
    Any luck with this? I have the same question – Justin May 18 '22 at 04:00
  • I've come to the conclusion that the popup that appears when the prompt is `none`, is a flaw in the UX. Perhaps they might fix it in the future, but for now, there is no where to report that to the google engineers. – Morfinismo May 20 '22 at 19:00
  • This seems basically... insane. To prompt a user every page load? Every time a token expires? That's not viable. There has to be some mistake. – Blunt Jackson Jun 20 '22 at 17:29
  • 1
    Your popup does NOT need to have the user sign in again, but it *will* flash. The key is to hint the popup with the signed-in user's email address. Details are in the reference. I also have a tutorial on this here: https://overclocked.medium.com/seamless-api-access-with-google-identity-services-b9901009a8ce – Blunt Jackson Jun 23 '22 at 19:52

2 Answers2

8

I have stepped through GIS library code and can confirm that prompt='' and prompt='none' are not implemented the way requestAccessToken documentation implies. GIS always opens a pop-up window. The prompt parameter only changes what happens in the pop-up. There is also no token storage or caching features in GIS, only in pop-up.

The current prompt parameter behavior looks by design based on OAuth 2.0 flow comparison table. The access token should be refreshed only when user invokes an action that requires it.

This leaves us with pretty awful UX experience where pop-up has to briefly open and close every hour or so. Alternative is to use the authorization code flow. But it requires to implement a mechanism to send access token back to the client side from backend.

v3nom
  • 395
  • 2
  • 5
  • 4
    This makes a pure-client side web app non-viable. I deeply regret attempting to migrate my app, and have lost my respect for Google. I am considering switching architectures completely. – Blunt Jackson Jun 20 '22 at 17:47
  • It turns out that { prompt: '' } on the requestAccessToken, along with hint: '' when initializing the token client *do* get the job done, although it is still a little awkward. I have a library in npm that makes this easier, or which at least can act as a reference implementation: https://www.npmjs.com/package/gothic – Blunt Jackson Jun 23 '22 at 19:54
  • @BluntJackson - when you use `prompt: ''` do you not get a popup? For me it still appears but then closes without user interaction. – Matt Sanders Nov 22 '22 at 21:54
-1

The button flow and consent popup behavior is intentional for browsers to obtain an access token, when configuring setting prompt to an empty string will suppress the user popup on every request: prompt=''.

Adopting the code model with auth code and exchanging the refresh token for access token is what you are looking for if you'd like to perform actions on behalf of the user without their being present or having to trigger a token request with a gesture such as a button press.

bdid
  • 485
  • 2
  • 6
  • 1
    The code model is only secure if done from a secure server. For a pure-client application, it's a terrible idea. – Blunt Jackson Jun 20 '22 at 22:11
  • Exactly right. This is one reason why refresh tokens and code model are no longer available for pure-client apps. – bdid Jul 15 '22 at 16:19