NeNaD
NeNaD

Reputation: 20304

Authenticate REST request to Google APIs

I have a problem authenticating a REST request to Google APIs. Usually, Google have client packages that do it for you.

Now, I am using Document Translation service, which is still in preview, so I can not use the package. Docs are really confusing when it comes to authenticating a REST request. When I am using a package, I am giving it a JSON credentials file with this template:

{
  "type": "xxx",
  "project_id": "xxx",
  "private_key_id": "xxx",
  "private_key": "xxx",
  "client_email": "xxx",
  "client_id": "xxx",
  "auth_uri": "xxx",
  "token_uri": "xxx",
  "auth_provider_x509_cert_url": "xxx",
  "client_x509_cert_url": "xxx"
}

Can I send a REST request and just use some of this data to authenticate, just like when I use the client packages? I saw in a few places that I should generate a token with this data and use a token to authenticate. Do I need to generate and use a token? If yes, how to create a token in NodeJS?

Upvotes: 0

Views: 483

Answers (1)

Tanaike
Tanaike

Reputation: 201378

I believe your current situation and your goal as follows.

  • You have the credential file of the service account.
  • You want to use the Google APIs using the service account.
  • You want to achieve this using Node.js. But, you don't want to use googleapis for Node.js. You want to use this service account without googleapis for Node.js.
  • Your question has following 2 questions.
    1. Can I send a REST request and just use some of this data to authenticate, just like when I use the client packages?
    2. Do I need to generate and use a token? If yes, how to create a token in NodeJS?

Answer for question 1:

I think that it's yes.

Answer for question 2:

I think that it's yes. In order to use Google APIs using the service account, it is required to retrieve the access token using the service account. The sample script for retrieving the access token from the service account without googleapis for Node.js is as follows.

Sample script:

In this case, 2 libraries of crypto and request are used. And, please set privateKey and clientEmail. This script is from this post.

const cryptor = require('crypto');
const request = require('request');

const privateKey = "-----BEGIN PRIVATE KEY-----\n###-----END PRIVATE KEY-----\n"; // private_key of JSON file retrieved by creating Service Account
const clientEmail = "###"; // client_email of JSON file retrieved by creating Service Account

const scopes = ["https://www.googleapis.com/auth/drive.readonly"]; // Sample scope

const url = "https://www.googleapis.com/oauth2/v4/token";
const header = {
  alg: "RS256",
  typ: "JWT",
};
const now = Math.floor(Date.now() / 1000);
const claim = {
  iss: clientEmail,
  scope: scopes.join(" "),
  aud: url,
  exp: (now + 3600).toString(),
  iat: now.toString(),
};

const signature = Buffer.from(JSON.stringify(header)).toString('base64') + "." + Buffer.from(JSON.stringify(claim)).toString('base64');

var sign = cryptor.createSign('RSA-SHA256');
sign.update(signature);
const jwt = signature + "." + sign.sign(privateKey, 'base64');

request({
  method: "post",
  url: url,
  body: JSON.stringify({
    assertion: jwt,
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
  }),
}, (err, res, body) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log(body);
});
  • In this sample, as a sample scope, https://www.googleapis.com/auth/drive.readonly is used. About this, please modify the scopes for your actual situation.

Result:

When above script is run, the following value is returned. You can use the access token from this value and can use the Google APIs using this access token.

{
  "access_token":"###",
  "expires_in":3599,
  "token_type":"Bearer"
}

Note:

  • As an important point, for example, when you use the Google Drive API using this script, the Drive of service account is different from your Google Drive. Please be careful this. When you want to use the file on your Drive using the service account, it is required to share the file with the email of service account.

References:

Upvotes: 1

Related Questions