Search code examples
javascriptgoogle-apigoogle-oauthgoogle-api-clientgoogle-identity

How to use scoped APIs with (GSI) Google Identity Services


Google recently sent me an email with the following:

One or more of your web applications uses the legacy Google Sign-In JavaScript library. Please migrate your project(s) to the new Google Identity Services SDK before March 31, 2023

The project in question uses the Google Drive API alongside the now legacy authentication client.

The table on the migration page (https://developers.google.com/identity/gsi/web/guides/migration) says:

Old New Notes
JavaScript libraries
apis.google.com/js/platform.js accounts.google.com/gsi/client Replace old with new.
apis.google.com/js/api.js accounts.google.com/gsi/client Replace old with new.

I was currently using gapi on the front-end to perform authorization which is loaded from apis.google.com/js/api.js. According to the table I would need to replace it with the new library.

I've tried the following to authenticate and authorize in the same manner that I used to do with gapi:

window.google.accounts.id.initialize({
  client_id: GOOGLE_CLIENT_ID,
  callback: console.log,
  scope: "https://www.googleapis.com/auth/drive.file",
  discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
});

window.google.accounts.id.renderButton(ref.current, {
  size: "medium",
  type: "standard",
});

However, when I try to authenticate with the Google Sign In button, the scope field is not respected and it does not ask the user to authorize the requested scopes. It also doesn't return any form of access token in the Credential Response in the callback.

I'm not sure how else to authorize using the new library.


Solution

  • To add to the current answer, there is now documentation on how to authorize users with additional scope. From Using the token model.

    First you need to init a TokenClient:

    const client = google.accounts.oauth2.initTokenClient({
      client_id: 'YOUR_GOOGLE_CLIENT_ID',
      scope: 'https://www.googleapis.com/auth/calendar.readonly',
      callback: (response) => {
        ...
      },
    });
    

    Then request for a token:

    client.requestAccessToken();
    

    If anyone is interested in where it's mentioned in the migration documentation, last paragraph of this section:

    If your use case includes authorization, please read How user authorization works and Migrate to Google Identity Services to make sure your application is using the new and improved APIs.

    While their articles are very detailed and good, personally I find them a bit too much for me, so it's simpler for me to just follow the first article mentioned and don't care about migrations at all.