google-apigoogle-drive-apigoogle-oauth

Getting started with Oauth for google Drive API Getting a 502 response from gapi.client.init


I'm trying to write a web client for google drive, but I'm stuck trying to get the authorization client to work. Specifically, when I call gapi.client.init() I'm getting a response of 502 - Bad Gateway. I followed the steps in this quickstart: https://developers.google.com/workspace/drive/api/quickstart/js. This is the code to my client:

<!DOCTYPE html>
<html>
  <head>
    <title>Drive API Quickstart</title>
    <meta charset="utf-8" />
  </head>
  <body>
    <p>Drive API Quickstart</p>

    <!--Add buttons to initiate auth sequence and sign out-->
    <button id="authorize_button" onclick="handleAuthClick()">Authorize</button>
    <button id="signout_button" onclick="handleSignoutClick()">Sign Out</button>

    <pre id="content" style="white-space: pre-wrap;"></pre>

    <script type="text/javascript">
      /* exported gapiLoaded */
      /* exported gisLoaded */
      /* exported handleAuthClick */
      /* exported handleSignoutClick */

      // TODO(developer): Set to client ID and API key from the Developer Console
      const CLIENT_ID = 'my client id';
      const API_KEY = 'my api key';

      // Discovery doc URL for APIs used by the quickstart
      const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

      // Authorization scopes required by the API; multiple scopes can be
      // included, separated by spaces.
      const SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';

      let tokenClient;
      let gapiInited = false;
      let gisInited = false;

      document.getElementById('authorize_button').style.visibility = 'hidden';
      document.getElementById('signout_button').style.visibility = 'hidden';

      /**
       * Callback after api.js is loaded.
       */
      function gapiLoaded() {
        gapi.load('client', initializeGapiClient);
      }

      /**
       * Callback after the API client is loaded. Loads the
       * discovery doc to initialize the API.
       */
      async function initializeGapiClient() {
        await gapi.client.init({
          apiKey: API_KEY,
          discoveryDocs: [DISCOVERY_DOC],
        });
        gapiInited = true;
        maybeEnableButtons();
      }

      /**
       * Callback after Google Identity Services are loaded.
       */
      function gisLoaded() {
        tokenClient = google.accounts.oauth2.initTokenClient({
          client_id: CLIENT_ID,
          scope: SCOPES,
          callback: '', // defined later
        });
        gisInited = true;
        maybeEnableButtons();
      }

      /**
       * Enables user interaction after all libraries are loaded.
       */
      function maybeEnableButtons() {
        if (gapiInited && gisInited) {
          document.getElementById('authorize_button').style.visibility = 'visible';
        }
      }

      /**
       *  Sign in the user upon button click.
       */
      function handleAuthClick() {
        tokenClient.callback = async (resp) => {
          if (resp.error !== undefined) {
            throw (resp);
          }
          document.getElementById('signout_button').style.visibility = 'visible';
          document.getElementById('authorize_button').innerText = 'Refresh';
          await listFiles();
        };

        if (gapi.client.getToken() === null) {
          // Prompt the user to select a Google Account and ask for consent to share their data
          // when establishing a new session.
          tokenClient.requestAccessToken({prompt: 'consent'});
        } else {
          // Skip display of account chooser and consent dialog for an existing session.
          tokenClient.requestAccessToken({prompt: ''});
        }
      }

      /**
       *  Sign out the user upon button click.
       */
      function handleSignoutClick() {
        const token = gapi.client.getToken();
        if (token !== null) {
          google.accounts.oauth2.revoke(token.access_token);
          gapi.client.setToken('');
          document.getElementById('content').innerText = '';
          document.getElementById('authorize_button').innerText = 'Authorize';
          document.getElementById('signout_button').style.visibility = 'hidden';
        }
      }

      /**
       * Print metadata for first 10 files.
       */
      async function listFiles() {
        let response;
        try {
          response = await gapi.client.drive.files.list({
            'pageSize': 10,
            'k
        } catch (err) {
          document.getElementById('content').innerText = err.message;
          return;
        }
        const files = response.result.files;
        if (!files || files.length == 0) {
          document.getElementById('content').innerText = 'No files found.';
          return;
        }
        // Flatten to string to display
        const output = files.reduce(
            (str, file) => `${str}${file.name} (${file.id})\n`,
            'Files:\n');
        document.getElementById('content').innerText = output;
      }
    </script>
    <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
    <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
  </body>
</html>

Here is the detail of the response from browser dev tools:

cb=gapi.loaded_0?le=scs:654 Uncaught (in promise)


WA {message: 'API discovery response missing required fields.', rZ: true, stack: 'gapix.client.GapiClientError: API discovery respon…u9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:168:116)'}


message: "API discovery response missing required fields."

rZ: true

stack: "gapix.client.GapiClientError: API discovery response missing required fields.\n    at new WA (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:654:159)\n    at c (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:706:48)\n    at gapi.loaded_0.e.xn._.xk.e.Er (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:175:25)\n    at Sk (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:178:59)\n    at Ok (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:177:368)\n    at Object.nz (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:177:238)\n    at jk (https://apis.google.com/\_/scs/abc-static/\_/js/k=gapi.lb.en.nJpyt-fjzo8.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9fTqXSCmwMDsu9FH68l5KSqr6MBg/cb=gapi.loaded_0?le=scs:168:116)"

[[Prototype]]: gapi.loaded_0._.lb


constructor: ƒ (a)

name: "gapix.client.GapiClientError"

[[Prototype]]: Error

The only changes I made to the code were to put in my client id and api key. I expected to see the Oauth consent screen, but instead I got the 502 response from Google's servers. I had this code working on another GCP project, but it doesn't seem to work on my new project. The difference between the two projects is that the current project is for a Google Workspace account. Any idea what I'm doing wrong?


Solution

  • In my case it was due to setting a wrong API KEY. make sure you have created one