bartekmo
bartekmo

Reputation: 218

client-side gcp api access - API_KEY_INVALID

it's weekend so I'm trying something new - the goal is to get a web app connect to GCP api using user's credentials and (for starters) let them choose a project and list their compute resources (let's say networks). I guess the way to go is JS Client on client side + oauth2.

I picked the JS client "complete example" from here https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#example registered my app, modified id/secret, changed the scope to "https://www.googleapis.com/auth/cloud-platform.read-only https://www.googleapis.com/auth/compute.readonly"

Now, it works fine if I just hard-code the project and list networks.

But as soon as I try to make a request like:

var request = gapi.client.request({
        'method': 'GET',
        'path': 'https://cloudresourcemanager.googleapis.com/v1/projects'
      })

or even (!) add "https://cloudresourcemanager.googleapis.com/$discovery/rest?version=v1" to discoveryDocs - I get 400 error "API key not valid. Please pass a valid API key."

I tried different scopes including the broadest https://www.googleapis.com/auth/cloud-platform mentioned in API Explorer, but to no avail. I obviously can list my available projects and same query via api explorer works fine.

Any idea what I'm missing?

Upvotes: 0

Views: 596

Answers (1)

bartekmo
bartekmo

Reputation: 218

OK, so here's what works for me:

The example posted at https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#example includes 2 types of authentication: OAuth2 and Access Token. While both work for Compute, @JohnHanley in comment above points out that only OAuth access token derived from a user or service account works with cloudresourcemanager API (the one used for projects and folders).

In my case it was enough to remove apiKey from gapi.client.init() call, which makes perfect sense since I wanted to use user's account, not mine. The modified initClient() from the example linked above looks like this:

function initClient() {
  gapi.client.init({
      'clientId': gapiClientId,
      'scope': gapiScope,
      'discoveryDocs': [
        'https://www.googleapis.com/discovery/v1/apis/compute/v1/rest',
        'https://cloudresourcemanager.googleapis.com/$discovery/rest?version=v1'
      ]
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

/* ... */

  })
}

Upvotes: 1

Related Questions