Understanding How to Access Google APIs
Tags: node, googlecloud, javascript, tutorial
Published: 2022-08-03 21:37:00

Google has an extensive library of APIs that developers can use to build powerful integrations for the web. Their 400-strong API library, ranges from Maps, Email, Calendar, Drive, Sheets, and a lot more. 

Today, we will explore how to access Google APIs using [OAuth 2.0 protocol](https://tools.ietf.org/html/rfc6749) for Server-side Web Applications. Here are a couple of assumptions that I'm taking here:

* You have a Google account
* Understand Node.js (or Next.js given that its API routes are Express-compliant)

If you need more in-depth documentation, please check the [Google Identity Documentation](https://developers.google.com/identity/protocols/oauth2).

Here's a diagram of what we're trying to accomplish today:

![OAuth 2.0 Protocol for Google APIs](https://res.cloudinary.com/dmca9ldbv/image/upload/v1659562357/blog/google-oauth/google_diagram_yhbhso.png)

## Why does OAuth matter?

OAuth allows users to share specific data with an application while keeping their usernames, passwords, and other information private. For example, we are building this example to create a *Calendar Management application*, therefore we want to access our Google Calendar to create, send and manage calendar invitations securely (disclaimer: we won't build the integration but only explore how to authorize our web application for it).

>A properly authorized web application can access an API while the user interacts with the application or after the user has left the application.

## Configuring Google Console

Let's enable an API for your project (we will use Google Calendar):

1. Open the [API Library](https://console.cloud.google.com/apis/library) in the Google API Console
2. If prompted, select a project, or create a new one
3. Select the API you want to enable, then click the *Enable* button
4. Open **API and Services > OAuth consent screen**
5. Create a User Type *Internal* application (you do not need to define Scopes here)
6. Open **API and Services > Credentials** 
7. Select the *Web application* application type
8. Fill in the form and click **Create**. Please specify authorized **redirect URLs** (for testing you can enable http://localhost:3000, but don't forget to add your production URL)
9. Safely store the `client_id`, `client_secret`, `redirect_url`.

## Identify your access scopes

Scopes enable your application to only request access to the resources that it needs. Here is a full list of scopes that you might use to access Google APIs: [OAuth 2.0 API Scopes](https://developers.google.com/identity/protocols/oauth2/scopes). Here's the example of the ones I selected for our Calendar application:

```typescript
const scopes: string[] = [
    "https://www.googleapis.com/auth/calendar",
    "https://www.googleapis.com/auth/calendar.events",
    "https://www.googleapis.com/auth/calendar.events.freebusy",
    "https://www.googleapis.com/auth/calendar.events.owned",
];
```

## Generate an Authorization URL

Before anything, you need to make sure to install the Node.js Google API Client  Library by running `$ npm install googleapis` and then call a request to run the following code:

```typescript
import type { NextApiRequest, NextApiResponse } from "next";
import { google } from "googleapis";

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    try {
        const oauth2Client = new google.auth.OAuth2(
            process.env.GOOGLE_CLIENT_ID,
            process.env.GOOGLE_CLIENT_SECRET,
            process.env.GOOGLE_REDIRECT_URL
        );

        const scopes: string[] = [
            "https://www.googleapis.com/auth/calendar",
            "https://www.googleapis.com/auth/calendar.events",
            "https://www.googleapis.com/auth/calendar.events.freebusy",
            "https://www.googleapis.com/auth/calendar.events.owned",
        ];

        const authorizationUrl: string = oauth2Client.generateAuthUrl({
            access_type: "offline",
            scope: scopes,
            include_granted_scopes: true,
        });

        res.status(200).json({ authorizationUrl });
    } catch (error) {
        console.log(error);
        res.status(500).json(error);
    }
}

```

Please refer to the [Error documentation](https://developers.google.com/identity/protocols/oauth2/web-server#authorization-errors) if you require more information.

If you get a response that contains the **Authorization URL**, go ahead and open it for Google to prompt for consent. In this step, the user grants the application the requested access by displaying a consent window with all the required information. 

### Before you grant consent!!!

**Developer note:** Yes! Ideally, you would handle the redirection and server response all from your application. However, our goal here is to get the credentials we require for our server-side web application to run independently, using an `access_token` and a `refresh_token` to revalidate whenever required on its own. Therefore, this process has been broken down for easy comprehension and to simplify our application's code.

Once you grant consent, the Browser will redirect you to your test URL `http://localhost:3000` (or any test URL you assigned when you configured your credentials). The URL will contain an authorization code that you need to store that looks like this:

```http
http://<REDIRECT_URL>/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
```

## Exchange Authorization Code for Access and Refresh Tokens

Once you store the authorization code, you can exchange this for an `access_token` and a `refresh_token`. Once your application has a refresh token, the access token will be acquired and refreshed automatically (as needed) at each call. Initially we will get both, set our credentials and send all the token information as a response:

```typescript
import type { NextApiRequest, NextApiResponse } from "next";
import { google } from "googleapis";

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    try {
        const oauth2Client = new google.auth.OAuth2(
            process.env.GOOGLE_CLIENT_ID,
            process.env.GOOGLE_CLIENT_SECRET,
            process.env.GOOGLE_REDIRECT_URL
        );

        const { tokens } = await oauth2Client.getToken(<AUTHORIZATION_CODE>);

        oauth2Client.setCredentials(tokens);

        res.status(200).json({ tokens });
    } catch (error) {
        console.log(error);
        res.status(500).json(error);
    }
}
```

Once we receive a response, we need to securely store the `refresh_token` for further calls.

## Using your Credentials to access Google APIs

Then at every request where we need to access Google APIs, we will pass in all the following before the integration:

```typescript
import type { NextApiRequest, NextApiResponse } from "next";
import { google } from "googleapis";

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    try {
        const oauth2Client = new google.auth.OAuth2(
            process.env.GOOGLE_CLIENT_ID,
            process.env.GOOGLE_CLIENT_SECRET,
            process.env.GOOGLE_REDIRECT_URL
        );

        oauth2Client.setCredentials({
            refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
        });

        /* Your Google API Integration */

        res.status(200);
    } catch (error) {
        console.log(error);
        res.status(500).json(error);
    }
}

```

From here you can refer to your specific Google API Documentation from their [Developers Google](https://developers.google.com/) website. Once you have start coding your integration, you will be able to authorize it by passing the `oauth2Client` as a parameter.

Remember this is a quick guide in understanding how to use OAuth 2.0 for Web Server Application for more information reference Google Documentation or shoot me a message at any of my socials!

Thanks for reading!