1
votes

I'm calling the Google Analytics Reporting API using google-api-nodejs-client to show the number of visits inside a blog.

This blog is hosted inside Google App Engine Standard Environment.

In development, I'm authenticating my API calls using the Application Default Credentials. I downloaded the JSON file with the credentials from the account service I created exclusively for analytics purposes, set the file to the Google_Application_Credentials environment variable and everything worked. I'm able to get the data from Google Analytics and display it in the website.

But this is not working in production. I suppose getClient() it's not getting the credentials in that environment.

Things to note: 1) I did not upload the downloaded JSON file with the credentials from the service account (I think it would be counter intuitive and unsafe to do that, and from what I understood in the docs, GCP is able to deal automatically with the API authentications);


const {google} = require("googleapis");

async function main () {

    // This method looks for the GCLOUD_PROJECT and GOOGLE_APPLICATION_CREDENTIALS
    // environment variables.
    const auth = await google.auth.getClient({
        // Scope of the analytics reporting,
        // with only reading access.
        scopes: 'https://www.googleapis.com/auth/analytics.readonly',
    });

    // Create the analytics reporting object
    const analyticsreporting = await google.analyticsreporting({
        version: 'v4',
        auth: auth,
    });

    // Fetch the analytics reporting
    const res = await analyticsreporting.reports.batchGet({...});
    return res.data;
}

I already run out of options. Can someone help me with this?

1
Google_Application_Credentials is ALL UPPER CASE. App Engine Identity: cloud.google.com/docs/authentication/… - John Hanley
@JohnHanley, this is not the problem. As I said, everything worked well in the development environment. The problem is in the production, which is configured and handled automatically by Google Cloud. - Arthur Brant
I want to know what part is missing. I've done everything that I found in the documentation. The only thing that I haven't done is to use the API App Engine App Identity because they didn't post anything related to Node.js yet. - Arthur Brant
I have a doubt. Do I need to upload to production my JSON file that contains my service account key and set it to GOOGLE_APPLICATION_CREDENTIALS to authenticate my API calls in production? Or this is only needed in development? - Arthur Brant
You can choose to authenticate with App Engine's default service account or by manually specifying a service account via the Json credentials file (the way you did in development). - John Hanley

1 Answers

2
votes

This is a problem with the default scopes and application default credentials. By default, if you don't create a new service account, you are going to get 'application default credentials' from the GCE metadata service: https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-nodejs

Those credentials usually only have the cloud-platform scope, and the set of scopes cannot be changed (as of today). To make this work, you have a few options.

  1. You could create a new service account, download the service account key, and use the keyFile property in the getClient method options to reference the key. If you do it this way, the scopes you pass into getClient will be respected.

  2. You could play with the scopes available to the service account under which your GAE application is running. I haven't personally tried that, but it theoretically should be possible.

Best of luck!