Authentication with Google in NodeJS
Tags: javascript, node, authentication, gmail
Published: 2019-10-02 20:11:42

While working on OAuth for a long time. I have finally understood the flow. But a few days back I had no idea how OAuth works and I was very frustrated and I need to implement it. So I just started to write some code and messing around with **Gmail** API. After scratching my head for the whole night I was able to login with google. So I thought I should share the process.

Now without further delay let's get started.

1) Goto [google developer console](https://console.developers.google.com).

2) Create a new project

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/qb0ejc955z3ibwfc6u6h.png)

3) Select the project and click **credentials** in the sidebar.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/cs8g1tnr983ye4daofu4.png)

4) Now select **OAuth client ID**

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/e27yy09upwbvsj126y42.png)

5) Now Select **Web Application** in application type. The name could be whatever you want, in **Authorized JavaScript origins** add this line

```
http://localhost:5000
```

and in **Authorized redirect URIs** field add this line

```
http://localhost:5000/auth/google/callback
```

and click on create.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hxx5tv94t8qfp06cf1lk.png)

6) Download the credentials *JSON* file by clicking on the tiny download button.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/c1y8jr8xktzyhgaqftyp.png)

Your credentials *JSON* file should look like this after few changes.

```javascript
{
    "client": {
        "id": "put you id here",
        "secret": "put your secret key here",
        "redirect": "http://localhost:5000/auth/google/callback"
    },

    // Don't change the code below this line

    "credentials": {
        "access_token": "your access_token",
        "token_type": "Bearer",
        "expires_in": 3600,
        "refresh_token": "your refresh_token"
    }
}
```


7) Now open your favorite code editor (mine is vscode) and create an `index.js` file and put the credential JSON file in the same folder.

8) run `npm init` command and just set all options to default.

9) Install express `npm i express` and google API package `npm i googleapis`

10) Rename your credential JSON file to `google_key.json`. Just an extra step you can name whatever you want.

11) Paste this code below in `index.js` file.

```javascript
const { google } = require('googleapis');
const express = require('express')
const OAuth2Data = require('./google_key.json')

const app = express()

const CLIENT_ID = OAuth2Data.client.id;
const CLIENT_SECRET = OAuth2Data.client.secret;
const REDIRECT_URL = OAuth2Data.client.redirect

const oAuth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL)
var authed = false;

app.get('/', (req, res) => {
    if (!authed) {
        // Generate an OAuth URL and redirect there
        const url = oAuth2Client.generateAuthUrl({
            access_type: 'offline',
            scope: 'https://www.googleapis.com/auth/gmail.readonly'
        });
        console.log(url)
        res.redirect(url);
    } else {
        const gmail = google.gmail({ version: 'v1', auth: oAuth2Client });
        gmail.users.labels.list({
            userId: 'me',
        }, (err, res) => {
            if (err) return console.log('The API returned an error: ' + err);
            const labels = res.data.labels;
            if (labels.length) {
                console.log('Labels:');
                labels.forEach((label) => {
                    console.log(`- ${label.name}`);
                });
            } else {
                console.log('No labels found.');
            }
        });
        res.send('Logged in')
    }
})

app.get('/auth/google/callback', function (req, res) {
    const code = req.query.code
    if (code) {
        // Get an access token based on our OAuth code
        oAuth2Client.getToken(code, function (err, tokens) {
            if (err) {
                console.log('Error authenticating')
                console.log(err);
            } else {
                console.log('Successfully authenticated');
                oAuth2Client.setCredentials(tokens);
                authed = true;
                res.redirect('/')
            }
        });
    }
});

const port = process.env.port || 5000
app.listen(port, () => console.log(`Server running at ${port}`));
```

12) Run `index.js`

Google will ask you to sign in and allow access. Then you will be signed in and as we are fetching only *Gmail* labels in this API. You will get output in the console like this.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/cqce78qsxhraoajqz2eo.png)


*Note:-* If you get some error due to not having https enabled don't panic. Click on *See more* button and allow google to access your profile manually.

Click on `show advance` and then click on `Go to 'your app name'(unsafe)` and allow it.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/99q0e4jeo1w78otve5it.png)

I hope this will help. I'll be back with another one, until then Bye.

![Bye Gif](https://media.giphy.com/media/kGCuRgmbnO9EI/giphy.gif)