Implement Google OAuth in NestJS using Passport
Tags: webdev, javascript, node, nestjs
Published: 2022-08-15 11:31:53

---
title: Implement Google OAuth in NestJS using Passport
published: true
description: This article teaches you how to use Passport to implement Google OAuth in a [NestJS](https://docs.nestjs.com/) application.
tags: #webdev #JavaScript #NodeJS #NestJS
cover_image: "https://res.cloudinary.com/chukwutosin/image/upload/ar_100:42,c_scale,h_420,w_1000/v1660562415/IMG_2237_onodwi.png"
---
## Introduction

Authentication is an essential part of most applications. Implementing authentication in your application depends on requirements specific to the application.

This article teaches you how to use Passport to implement Google OAuth in a [NestJS](https://docs.nestjs.com/) application.

NestJS is a [Node.js](https://nodejs.dev/) framework for building server-side applications. NestJS supports typescript out of the box. On the other hand, Passport is an authentication middleware for Node.js that supports over 500 authentication strategies, e.g., username and password, google, Facebook, etc.

## Prerequisite

You need to have:

- A basic understanding of JavaScript. TypeScript is preferred but not mandatory.
- Basic knowledge of the NestJS framework.
- A Google account — create one for free [here](https://www.google.com/).

## Repository

Find the completed project on GitHub: https://github.com/folucode/google-oauth-app

## Creating a NestJs Application

To get started, install [Node.js](https://nodejs.dev/) if you don’t already have it installed. Download the version compatible with your Operating System and follow the installation instructions.

You can verify that [Node.js](https://nodejs.dev/) is installed successfully by running the command below:

    $ node -v
    // v18.4.0 - node version printed to the terminal

Next, to scaffold a NestJS project using the [Nest CLI](https://docs.nestjs.com/cli/overview) (short for **command line interface**), run the commands below in your terminal:

    $ npm i -g @nestjs/cli
    $ nest new <project-name>

The commands above install NestJS CLI globally on your computer and creates a new project directory with your supplied project name. The created project directory has all the core NestJS starter files and modules.

To start the NestJS development server, run the command below in the project directory:

    $ npm run start:dev

## Creating an App on Google Console

Before using any Google OAuth in your project, you must create an app on [Google Cloud Console](https://console.cloud.google.com/projectcreate). Fill in the project name, click `CREATE`, and navigate to the app dashboard.

!["create google console app"](https://paper-attachments.dropbox.com/s_D1A4C48D2702290FB9AA3C5708887A738AEDBB43A8EFD98F0CBA62709974998F_1660216942314_Screenshot+2022-08-10+at+10.50.36.png)

### Setting OAuth Consent Screen

Click on the `OAuth consent screen` from the sidebar, select `External` and click `CREATE`.

![Setting OAuth Consent Screen](https://paper-attachments.dropbox.com/s_D1A4C48D2702290FB9AA3C5708887A738AEDBB43A8EFD98F0CBA62709974998F_1660217197013_Screenshot+2022-08-10+at+11.01.00.png)

Selecting the option `External` means any google account can use this app. On the next page, make sure only to fill the following as this is a test application:

- **Application Name**
- **User support email**
- **Developer contact information**

Click `SAVE` AND `CONTINUE`. On the next page,

1. Click `ADD OR REMOVE SCOPES`
2. Select the first two options and click `UPDATE` to save the changes.
3. Click `SAVE AND CONTINUE` and complete the subsequent steps.
   ![Setting OAuth Consent Screen](https://paper-attachments.dropbox.com/s_D1A4C48D2702290FB9AA3C5708887A738AEDBB43A8EFD98F0CBA62709974998F_1660315238619_Screenshot+2022-08-10+at+11.13.58.png)

### Get API keys

Go to your app [dashboard](https://console.cloud.google.com/apis/credentials). At the top of the page, click on `CREATE CREDENTIALS` and select the **OAuth client ID** option. Follow the next steps:

1. Select your application type, in this case, **Web Application**.
2. Fill in the **name** field or go with the default name.
3. Set the **Authorized JavaScript origin** and **Authorized redirect URI** fields. For this app, use http://localhost:3000 and http://localhost:3000/auth/google-redirect, respectively.
4. Copy the **Client ID** and **Client Secret** or download it as JSON. The keys are always available on your app dashboard.

## Setup Google OAuth

In the project directory, run the following commands:

    npm i --save @nestjs/passport passport passport-google-oauth20 @nestjs/config
    npm i -D @types/passport-google-oauth20

Create a new file in the `src` folder named `google.strategy.ts`. In the file, paste the following code:

    import { PassportStrategy } from '@nestjs/passport';
    import { Strategy, VerifyCallback } from 'passport-google-oauth20';
    import { Injectable } from '@nestjs/common';

    @Injectable()
    export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
      constructor() {
        super({
          clientID: process.env.GOOGLE_CLIENT_ID,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET,
          callbackURL: 'http://localhost:3000/auth/google-redirect',
          scope: ['email', 'profile'],
        });
      }
      async validate(
        accessToken: string,
        refreshToken: string,
        profile: any,
        done: VerifyCallback,
      ): Promise<any> {
        const { name, emails, photos } = profile;
        const user = {
          email: emails[0].value,
          firstName: name.givenName,
          lastName: name.familyName,
          picture: photos[0].value,
          accessToken,
          refreshToken,
        };
        done(null, user);
      }
    }

In this file,

1. We first import the necessary dependencies.
2. The `PassportStrategy` class is a module in the ‘**@nestjs/passport**’ package. A class called `GoogleStrategy` extends the `PassportStrategy`. Note that every strategy class that uses **Passport** must extend the `PassportStrategy` class.
3. In the `super` method, we instantiate the `clientID`, `clientSecret`, callbackURL, and `scope` properties in the **constructor** function.
   1. The `clientID` and clientSecret are your application‘s ID and Secret key from Google when you created the app.
   2. The `callbackURL` is the endpoint in your app google will redirect to after authenticating a user.
   3. The `scope` is an array of the specific user information you want to get back from google.
4. The `validate` method executes after Google returns the requested user information. In this method, you decide what to do with the user information returned by Google. You then return the result using the done method.

### Store keys in environment variables

In the root of the project folder, create a `.env` file and put the Client ID and Client Secret keys in it.

    GOOGLE_CLIENT_ID= <your-client-id>
    GOOGLE_CLIENT_SECRET= <your-client-secret>

### Create Google OAuth Guard

To use Google OAuth Strategy in the endpoints, you need a Guard Class that extends the `AuthGuard` class and specifies **google** as the strategy to use.

Now, in the `src` folder, create a `google-oauth.guard.ts` file and paste the following code in it:

    import { Injectable } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { AuthGuard } from '@nestjs/passport';

    @Injectable()
    export class GoogleOAuthGuard extends AuthGuard('google') {
      constructor(private configService: ConfigService) {
        super({
          accessType: 'offline',
        });
      }
    }

**Note:** we specify `accessType` to be **offline** so that Google can return a refresh token after successful authentication.

### Create Auth routes

Open the `app.controller.ts` file in the src folder and replace its content with the code below. In this code, there are two routes. The first initializes Google authentication, and the other is the callback Google calls after authentication.

Also, notice that both routes use the `GoogleOAuthGuard`.

    import { GoogleOAuthGuard } from './google-oauth.guard';
    import { Controller, Get, Request, UseGuards } from '@nestjs/common';
    import { AppService } from './app.service';

    @Controller('auth')
    export class AppController {
      constructor(private readonly appService: AppService) {}

      @Get()
      @UseGuards(GoogleOAuthGuard)
      async googleAuth(@Request() req) {}

      @Get('google-redirect')
      @UseGuards(GoogleOAuthGuard)
      googleAuthRedirect(@Request() req) {
        return this.appService.googleLogin(req);
      }
    }

**Note:** The `googleLogin` method doesn’t exist yet. You would get an error for that.

## Return the user data after login

In the `app.service.ts` file, replace the contents with this code code:

    import { Injectable } from '@nestjs/common';

    @Injectable()
    export class AppService {
      googleLogin(req) {
        if (!req.user) {
          return 'No user from google';
        }

        return {
          message: 'User information from google',
          user: req.user,
        };
      }
    }

The `googleLogin` method returns either a ‘**No user from google**’ error if the authentication failed or the user information if the authentication is successful.

### Tie it all together

The app can’t know to use GoogleStrategy until you tell it. In the `app.module.ts` file, import the `GoogleStrategy` class and add it as a service in the providers array.

You also need to load the environment variables into the app. Do that by importing the `ConfigModule` class from the **“@nestjs/config”** package and call its **forRoot** method in the imports array.

    import { GoogleStrategy } from './google.strategy';
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { ConfigModule } from '@nestjs/config';

    @Module({
      imports: [ConfigModule.forRoot()],
      controllers: [AppController],
      providers: [AppService, GoogleStrategy],
    })
    export class AppModule {}

Run the app using the command below and navigate to `localhost:3000/auth` to test the app

    $ npm run start:dev

## Conclusion

This article showed you how to implement Google OAuth sign-in using Passport in NestJS applications.

## Resources

- [NestJS documentation](https://docs.nestjs.com/)
- [Passport Documentation](https://www.passportjs.org/)
- [Google OAuth Documentation](https://developers.google.com/identity/protocols/oauth2)

## Connect

Feel free to connect with me across my social media handles

- [LinkedIn](https://www.linkedin.com/in/tosin-moronfolu-273438120/)
- [Twitter](https://twitter.com/chukwutosin_)
- [Instagram](https://www.instagram.com/chukwutosin_/)