9-setting-up-oauth-20-authentication-in-a-nestjs-application.html

Setting Up OAuth 2.0 Authentication in a NestJS Application

In today’s digital landscape, securing your applications is more crucial than ever. OAuth 2.0 has become the standard for granting third-party applications limited access to a user’s resources without exposing their credentials. If you're developing a NestJS application, integrating OAuth 2.0 can enhance your security and user experience. This article will guide you through the process of setting up OAuth 2.0 authentication in a NestJS application, providing clear code examples and actionable insights to help you along the way.

What is OAuth 2.0?

OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It allows users to grant access to their resources on one site to another site without sharing their credentials. Common use cases include:

  • Social Login: Allowing users to log in using their Google or Facebook accounts.
  • API Access: Providing third-party apps access to user data securely.
  • Delegated Permissions: Allowing users to grant specific permissions to different applications.

Getting Started with NestJS

NestJS is a progressive Node.js framework for building efficient and scalable server-side applications. It leverages TypeScript and supports modular architecture, making it an excellent choice for implementing OAuth 2.0.

Prerequisites

Before diving into implementation, ensure you have the following:

  • Node.js installed (version 12 or above).
  • NestJS CLI installed globally. You can install it using: bash npm install -g @nestjs/cli
  • A NestJS application set up. You can create one using: bash nest new oauth-nestjs

Step 1: Install Required Packages

To set up OAuth 2.0 in your NestJS application, you need several packages. Install them using npm:

npm install @nestjs/passport passport passport-google-oauth20 express-session

Step 2: Create the Authentication Module

Create a new module for authentication:

nest generate module auth

Next, create an authentication service and controller:

nest generate service auth/auth
nest generate controller auth/auth

Step 3: Configure the Passport Strategy

In the auth module, configure the Google OAuth strategy. Create a new file google.strategy.ts in the auth folder.

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
import { AuthService } from './auth.service';

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(private readonly authService: AuthService) {
    super({
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: 'http://localhost:3000/auth/google/callback',
      scope: ['profile', 'email'],
    });
  }

  async validate(accessToken: string, refreshToken: string, profile: any) {
    const user = await this.authService.validateUser(profile);
    return user;
  }
}

Step 4: Implement the Authentication Logic

In your auth.service.ts, implement the logic to validate users:

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

@Injectable()
export class AuthService {
  async validateUser(profile: any): Promise<any> {
    // Here, you would typically find or create a user in your database
    return {
      id: profile.id,
      email: profile.emails[0].value,
      name: profile.displayName,
    };
  }
}

Step 5: Set Up Routes and Session Management

In your auth.controller.ts, set up routes for handling authentication:

import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express';

@Controller('auth')
export class AuthController {
  @Get('google')
  @UseGuards(AuthGuard('google'))
  async googleLogin(@Req() req: Request) {
    // Initiates the Google OAuth flow
  }

  @Get('google/callback')
  @UseGuards(AuthGuard('google'))
  googleLoginCallback(@Req() req: Request, @Res() res: Response) {
    // Successful authentication, redirect or respond with user data
    res.redirect('http://localhost:3000/dashboard'); // Redirect to your dashboard
  }
}

Step 6: Configure Session Management

To manage user sessions, configure session middleware in your main application file (main.ts):

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as session from 'express-session';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(
    session({
      secret: 'your_secret_key',
      resave: false,
      saveUninitialized: false,
    }),
  );
  await app.listen(3000);
}
bootstrap();

Step 7: Environment Variables

Create a .env file at the root of your project to store sensitive information:

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

Make sure to replace your_google_client_id and your_google_client_secret with your actual credentials from Google Developer Console.

Step 8: Testing the Setup

Now that everything is set up, run your NestJS application:

npm run start

Visit http://localhost:3000/auth/google to initiate the OAuth flow. Upon successful login, you will be redirected to your dashboard.

Troubleshooting Common Issues

  • Invalid Credentials: Ensure that your Google OAuth client ID and secret are set correctly in the .env file.
  • Callback URL Mismatch: Verify that your callback URL matches the one registered in the Google Developer Console.
  • Session Issues: Ensure that session middleware is correctly configured in the main application file.

Conclusion

Setting up OAuth 2.0 authentication in a NestJS application can significantly enhance your user experience and security. By following the steps outlined in this article, you can integrate Google authentication seamlessly. As you expand your application, consider adding more strategies or customizing user roles to fit your needs. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.