4

I have a cloud function in Node.JS on Google Cloud, I need to make GET request to Google and it requires an auth token. Using curl you can generate one using $(gcloud auth application-default print-access-token). But this doesn't work in Cloud instance so how I can generate one?

Some of the function:

exports.postTestResultsToSlack = functions.testLab
  .testMatrix()
  .onComplete(async testMatrix => {

    if (testMatrix.clientInfo.details['testType'] != 'regression') {
      // Not regression tests
      return null;
    }

    const { testMatrixId, outcomeSummary, resultStorage } = testMatrix;

    const projectID = "project-feat1"
    const executionID = resultStorage.toolResultsExecutionId
    const historyID = resultStorage.toolResultsHistoryId

    const historyRequest = await axios.get(`https://toolresults.googleapis.com/toolresults/v1beta3/projects/${projectID}/histories/${historyID}/executions/${executionID}/environments`, {
      headers: {
        'Authorization': `Bearer $(gcloud auth application-default print-access-token)`,
        'X-Goog-User-Project': projectID
      }
    });
George
  • 322
  • 1
  • 6
  • 25
  • Are you facing any error while doing this? If so, could you provide your error here? – Akshansha Singhal Nov 05 '21 at 01:36
  • ```Error: Request failed with status code 401``` – George Nov 05 '21 at 10:33
  • Check out the [document](http://cloud/functions/docs/securing/authenticating#generating_tokens_programmatically) on generating tokens programmatically using Nodejs. This [document](https://cloud.google.com/functions/docs/troubleshooting) speaks about the 401 error and its solution. Also I have found some threads similar to your issue, check out these once: [Thread1](https://stackoverflow.com/q/61677881), [Thread2](https://stackoverflow.com/q/60265116), [Thread3](https://stackoverflow.com/q/66428509) – Akshansha Singhal Nov 06 '21 at 06:54
  • The first link is broken. – George Nov 06 '21 at 11:54
  • Try this one: [Link](https://cloud.google.com/functions/docs/securing/authenticating#generating_tokens_programmatically) – Akshansha Singhal Nov 07 '21 at 06:31

1 Answers1

6

After countless hours spent, I stumbled across the answer scrolling through auto complete suggestions. Google has documentation about authentication but none mention this what you need for Cloud Functions to make API requests:

const {GoogleAuth} = require('google-auth-library');

const auth = new GoogleAuth();
const token = await auth.getAccessToken()

const historyRequest = await axios.get(
`https://toolresults.googleapis.com/toolresults/v1beta3/projects/${projectID}/histories/${historyID}/executions/${executionID}/environments`, 
      {
        headers: {
          'Authorization': `Bearer ${token}`,
          'X-Goog-User-Project': projectID
        }
    });
George
  • 322
  • 1
  • 6
  • 25
  • 1
    Note that you need to define the GOOGLE_APPLICATION_CREDENTIALS environment variable for this to work. Also, I had to give an explicit scopes string to the constructor `const auth = new GoogleAuth({scopes: 'https://www.googleapis.com/auth/cloud-platform'});` otherwise you get the following on .getAccessToken(): 400 Bad Request `{ error: 'invalid_scope', error_description: 'Invalid OAuth scope or ID token audience provided.' }` – masterxilo Jan 14 '22 at 20:56
  • see https://cloud.google.com/storage/docs/reference/libraries#client-libraries-install-nodejs or https://github.com/googleapis/google-auth-library-nodejs for more – masterxilo Jan 14 '22 at 20:57