4
votes

Does anyone here have experience running a NodeJS application on GAE flex environment?

I have a specific question about authenticating to non-cloud platform Google APIs (E.g. Google Drive, Google Sheets, etc and not Cloud Storage, etc).

I've been using Google's ADC and a following the method described here: https://github.com/google/google-api-nodejs-client#choosing-the-correct-credential-type-automatically

This worked for me previously - I was able to use ADC to authenticate with Cloud KMS & cloud storage.

But, I am unable to ship a a feature using the Google Sheets API (it writes data to a sheet based on user interaction, so that I can give this data super easily to the business team) as it runs locally with ADC and the service client keyfile that creates a JWT, but does not run in production.

As there aren't any concrete examples on this for NodeJS I ended up going down the rabbit hole of looking through the separate node docs to solve my issue.

In particular, the Sheets API states that I need to use OAuth 2, but these docs say it's better for me to stick with ADC: - https://cloud.google.com/appengine/docs/flexible/nodejs/authorizing-apps#oauth_20_authorization - https://developers.google.com/identity/protocols/OAuth2ServiceAccount

And why would it work with my local copy of my GAE service account's JWT, but not the Compute engine service account? I've added both appengine and compute engine service account emails to the spreadsheet with Write access, but it doesn't seem to work for the latter.

i keep running into the same error where my code works locally and I can append values to a sheet where my app engine email has access to write to, but in production, I continue to get the same error which says the app has insufficient permissions: `"The Sheets API returned an error: Error: A Forbidden error was returned while attempting to retrieve an access token for the Compute Engine built-in service account. This may be because the Compute Engine instance does not have the correct permission scopes specified. Request had insufficient authentication scopes." So i've also done domain wide authority delegation, and done every single thing I about adding the right access can find.

My main question is, will I be able to continue using the method laid out in this code (https://github.com/google/google-api-nodejs-client#choosing-the-correct-credential-type-automatically), or should I be using OAuth2 as in this documentation (https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests)? And if I need to use OAuth2, what's the point of even being on GAE if I can't even access Google's Sheets API without loading my own credentials in my env variables?

Am I doing something wrong?

2
I found a similar concern here in the community on "Accessing a Google Drive spreadsheet from Appengine", see if that helps youDigil
@Digil thanks for the tip! I had a look at it, and makes sense, however as it was posted a year ago, I was wondering if things have changed since, esp on the flex environment.. It's just a bit of a shame that the GAE docs constantly say that using the ADC is the best way for my program to "automatically" determine the right credentials needed, and yet I have to consider this special case and use OAuth2 on a machine running on GCP, trying to access another service owned by Google.. I'll have a think and if there's really no way for me to make ADC work, i'll probably have to do it. Thank you!parisandmilo
For using the OAuth 2.0 to Access Google APIs you can check this link. You can enable Google Sheets API directly from there.Digil
I already did that, but my question still remains... does the node library function for ADC support "automatically" generating these credentials or not? I'm not sure, and it's hard to tell from the documentation, as it works locally, which means it must be generating the right credentials from JWT, but not on production within GCP?parisandmilo

2 Answers

2
votes

I recently wrote NodeJS code that writes to a spreadsheet. It uses a service account and creates a JWT from a key file. My code runs as a Cloud Function, but perhaps it would give you ideas for how to solve your problem in GAE.

1
votes

As mentioned by Martin, you can access Google Sheets via the Google Sheets API with the Node Client library. I'd follow that link for details.

Here's a summary:

  1. Create a service account. Name it credentials.json.
  2. Enable the Google Sheets API
  3. Copy the email address found from step 1.
  4. Share the Google Sheet with the email address.
  5. Call the Google Sheets API, authorizing with the credentials created above.

Links: