How to authenticate to any Google API
By Flavio Copes
Learn how to authenticate to any Google API through the Developers Console: create a project, set up service credentials, and use the JSON key file.
This article explains how to use the Google Developers Console to authenticate to any of the Google APIs.
The Developers Console can be complicated to get right, and it’s one of the reasons I sometimes have resistance to using one of the Google APIs.
Let’s see how that works, in a very simple way.
This guide assumes you already have a Google account. Once you can authenticate, my post on how to interact with the Google Analytics API using Node.js shows what you can do with it.
- Create a new Google API Project
- Create the Authentication Credentials
- Service to Service API
- Using the JSON Key File
- Use environment variables
- Access other APIs
Create a new Google API Project
Create a new project, if you haven’t done it yet.
From the dashboard click Create a new project.
Give it a name, and you’ll be redirected to the project dashboard.
Add an API by clicking Enable APIs and services.
From the list, search the API you’re interested in and enable it.
That’s it! The project is now ready, you can go on and create the authentication credentials.
If you want to follow the Analytics examples below, enable the Google Analytics Data API. It’s the one that works with GA4 properties.
Create the Authentication Credentials
There are 3 ways to authenticate with the Google APIs:
- OAuth 2
- Service to Service
- API key
API key is less secure and restricted in scope and usage by Google.
OAuth 2 is meant to let your app make requests on behalf of a user, and as such the process is more complicated than needed, and requires exposing URLs to handle callbacks. Way too complex for simple uses.
In a Service to Service authentication model, the application directly talks to the Google API, using a service account, by using a JSON Web Token (JWT).
This is the simplest method, especially if you’re building a prototype or an application that talks from your server (like a Node.js app) to the Google APIs. This is the one method I’ll talk about for the rest of the article.
Service to Service API
To use this method you need to first generate a JSON Key File through the Google Developers Console.
There is another option which involves downloading a
.p12file and then converting it to apemfile using theopensslcommand. It’s no longer recommended by Google, just use JSON.
From a project dashboard, open Credentials, click Create credentials and choose Service account. Once the account exists, open it, go to the Keys tab and add a new JSON key. Google split this into two steps at some point. When I first wrote this post there was a single “Service Account Key” option, with a form where you picked the “JSON” key type.
That’s it! The browser downloads a JSON file.
This is the content of this JSON file, called JSON Key File:
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "...",
"client_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "..."
}
Using the JSON Key File
The simplest way is to put the JSON file somewhere reachable by your program, on the filesystem.
For example I have a test app under ~/dev/test, so I put the JSON file into that folder, and renamed it to auth.json. Then inside a Node.js app make sure the GOOGLE_APPLICATION_CREDENTIALS environment variable points to that file location on the filesystem.
Install the googleapis package. I tested this with version 181, but the package bumps its major version every few weeks, so any recent version works the same:
npm install googleapis
You create a JSON Web Token using the properties contained in the file:
const jwt = new google.auth.JWT({
email: key.client_email,
key: key.private_key,
scopes
})
and you pass that to any API request you make.
If you find older examples that call new google.auth.JWT(email, null, key, scopes) with separate arguments, they don’t work anymore. That form was removed in google-auth-library 10, the package googleapis uses for auth. The constructor now ignores those arguments, so you get a JWT with no email and no key, and every request fails with an authentication error.
This is an example of how to use it with the Google Analytics Data API (the GA4 one). process.env.GOOGLE_APPLICATION_CREDENTIALS is better set outside the program, but I added it in the source for clarity:
'use strict'
const { google } = require('googleapis')
const key = require('./auth.json')
const scopes = 'https://www.googleapis.com/auth/analytics.readonly'
const jwt = new google.auth.JWT({
email: key.client_email,
key: key.private_key,
scopes
})
const propertyId = 'XXXXXXXXX' // GA4 property ID (digits)
process.env.GOOGLE_APPLICATION_CREDENTIALS = './auth.json'
async function main() {
await jwt.authorize()
const analyticsdata = google.analyticsdata('v1beta')
const result = await analyticsdata.properties.runReport({
auth: jwt,
property: `properties/${propertyId}`,
requestBody: {
dateRanges: [{ startDate: '30daysAgo', endDate: 'today' }],
metrics: [{ name: 'screenPageViews' }]
}
})
console.log(result.data)
}
main().catch(console.error)
The first version of this post used google.analytics('v3') and data.ga.get(). That was the Universal Analytics API, which Google switched off in July 2024, so that code doesn’t work anymore.
Use environment variables
This is not ideal in many situations where having your private information on the filesystem is either not practical or not secure. For example if you’re using Heroku, it’s best to avoid putting the authentication credentials in the repository, and instead set them through the interface or console Heroku provides.
Or it’s the case of using it on Glitch prototypes, where environment variables are hidden to everyone except you.
In this case the best thing is to use environment variables, and store the content you need from the JSON file. In the following example, all we need are the client_email and private_key variables set in the JSON, so we can extract those and set them as environment variables, to keep them private.
'use strict'
const { google } = require('googleapis')
const scopes = 'https://www.googleapis.com/auth/analytics.readonly'
const jwt = new google.auth.JWT({
email: process.env.CLIENT_EMAIL,
key: process.env.PRIVATE_KEY,
scopes
})
const propertyId = process.env.GA4_PROPERTY_ID
async function main() {
await jwt.authorize()
const analyticsdata = google.analyticsdata('v1beta')
const result = await analyticsdata.properties.runReport({
auth: jwt,
property: `properties/${propertyId}`,
requestBody: {
dateRanges: [{ startDate: '30daysAgo', endDate: 'today' }],
metrics: [{ name: 'screenPageViews' }]
}
})
console.log(result.data)
}
main().catch(console.error)
Access other APIs
I used the Google Analytics Data API in the examples.
The google object makes it reachable at google.analyticsdata('v1beta').
v1beta is the API version. The Data API has been “beta” for years, and v1beta is the version the client library exposes.
Other APIs are reachable using a similar way:
google.drive('v3')google.youtube('v3')
When I first wrote this post my other example was google.urlshortener('v1'). Google shut that service down in 2019.
Want me to talk about your product? You can sponsor this site.
Related posts about services: