logologo
  • AI Tools

    DB Query GeneratorMock InterviewResume BuilderLearning Path GeneratorCheatsheet GeneratorAgentic Prompt GeneratorCompany ResearchCover Letter Generator
  • XpertoAI
  • MVP Ready
  • Resources

    CertificationsTopicsExpertsCollectionsArticlesQuestionsVideosJobs
logologo

Elevate Your Coding with our comprehensive articles and niche collections.

Useful Links

  • Contact Us
  • Privacy Policy
  • Terms & Conditions
  • Refund & Cancellation
  • About Us

Resources

  • Xperto-AI
  • Certifications
  • Python
  • GenAI
  • Machine Learning

Interviews

  • DSA
  • System Design
  • Design Patterns
  • Frontend System Design
  • ReactJS

Procodebase © 2024. All rights reserved.

Level Up Your Skills with Xperto-AI

A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.

Launch Xperto-AI

Authentication with Passport in NestJS

author
Generated by
ProCodebase AI

10/12/2024

NestJS

Sign in to read full article

Authentication is a critical aspect of modern web applications, and NestJS makes it simpler to implement robust authentication mechanisms using Passport. Whether you're building a REST API or a traditional web application, integrating authentication into your project is essential for securing user data and managing access control.

What is Passport?

Passport is a middleware for Node.js that simplifies the implementation of various authentication strategies. From simple username/password to OAuth, it provides a wide array of options to fit various use cases. When used with NestJS, it allows for clean and organized authentication practices consistent with the framework's philosophy.

Setting Up NestJS with Passport

To start, ensure you have a NestJS project set up. If you haven't set up one yet, simply create a new Nest application:

$ npm i -g @nestjs/cli $ nest new nest-auth-example $ cd nest-auth-example

Installing Dependencies

Next, install the necessary packages for Passport and JWT (JSON Web Tokens):

$ npm install @nestjs/passport passport passport-local @nestjs/jwt passport-jwt bcrypt

Here's a quick rundown of what each package does:

  • @nestjs/passport: A NestJS module for integrating Passport.
  • passport: The core Passport library.
  • passport-local: This strategy allows username/password authentication.
  • @nestjs/jwt: JWT module for generating tokens.
  • passport-jwt: This strategy provides authentication using JWT.
  • bcrypt: A library to hash passwords for a secure authentication process.

Creating the User Module

Before we dive into authentication, we'll need to set up a user model that our authentication strategies will use. Create a user module by running:

$ nest generate module users $ nest generate service users

Create a simple user entity, such as:

// src/users/user.entity.ts import { Exclude } from 'class-transformer'; export class User { id: number; username: string; @Exclude() password: string; }

User Service Implementation

In the users.service.ts, implement basic features to manage users:

// src/users/users.service.ts import { Injectable } from '@nestjs/common'; import { User } from './user.entity'; @Injectable() export class UsersService { private readonly users: User[] = []; async create(username: string, password: string): Promise<User> { const user = new User(); user.id = this.users.length + 1; user.username = username; user.password = await this.hashPassword(password); this.users.push(user); return user; } async findOne(username: string): Promise<User | undefined> { return this.users.find(user => user.username === username); } private async hashPassword(password: string): Promise<string> { return bcrypt.hash(password, 10); } }

Here, we have basic logic to create a user and find one based on the username.

Implementing the Local Strategy

Next, integrate the Passport Local strategy to handle user login:

// src/auth/local.strategy.ts import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-local'; import { UsersService } from '../users/users.service'; import { User } from '../users/user.entity'; @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private readonly usersService: UsersService) { super({ usernameField: 'username' }); } async validate(username: string, password: string): Promise<User> { const user = await this.usersService.findOne(username); if (!user || !(await bcrypt.compare(password, user.password))) { throw new UnauthorizedException(); } return user; } }

Handling JWT Authentication

Now, let's create JWT strategies for generating tokens:

  1. Create a new authentication module:
$ nest generate module auth
  1. Implement JWT strategy:
// src/auth/jwt.strategy.ts import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { UsersService } from '../users/users.service'; import { User } from '../users/user.entity'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(private readonly usersService: UsersService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: 'your_secret_key', // Change this to your actual secret }); } async validate(payload: any): Promise<User> { return this.usersService.findOne(payload.username); } }
  1. Create a login method in auth.service.ts to generate the JWT:
// src/auth/auth.service.ts import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { UsersService } from '../users/users.service'; @Injectable() export class AuthService { constructor(private usersService: UsersService, private jwtService: JwtService) {} async login(username: string): Promise<{ access_token: string }> { const user = await this.usersService.findOne(username); const payload = { username: user.username, sub: user.id }; return { access_token: this.jwtService.sign(payload), }; } }

Creating the Authentication Controller

Lastly, create an authentication controller to handle the incoming requests:

// src/auth/auth.controller.ts import { Controller, Post, Request, UseGuards } from '@nestjs/common'; import { AuthService } from './auth.service'; import { LocalAuthGuard } from './local-auth.guard'; // You need to create this guard @Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @UseGuards(LocalAuthGuard) @Post('login') async login(@Request() req) { return this.authService.login(req.user); } }

Securing Routes with Guards

To protect your routes, you can use guards. For example, to use the JWT strategy:

// src/auth/jwt-auth.guard.ts import { Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') {}

Now, you can secure any route by applying @UseGuards(JwtAuthGuard).

Testing the Authentication Flow

With the authentication flow set up, you can test it via Postman or any other API client:

  1. Register a User: Make a POST request to your user registration endpoint (not implemented in detail here but can be derived from UsersService).

  2. Login: Send a POST request to /auth/login with the username and password.

  3. Access Protected Route: Use the received JWT token as a Bearer token to access protected routes.

This setup provides you with a solid foundation for incorporating authentication into your NestJS application. Feel free to enhance this system with additional features such as refresh tokens, social logins, etc. The power of NestJS combined with Passport's flexibility opens numerous avenues for building secure and scalable applications.

Popular Tags

NestJSAuthenticationPassport

Share now!

Like & Bookmark!

Related Collections

  • NestJS Mastery: Modern Backend Development

    10/12/2024 | NestJS

Related Articles

  • Validation with Class Validator and Class Transformer in NestJS

    10/12/2024 | NestJS

  • Understanding Modules in NestJS

    10/12/2024 | NestJS

  • Performance Optimization in NestJS Applications

    10/12/2024 | NestJS

  • Testing in NestJS using Jest

    10/12/2024 | NestJS

  • Caching in NestJS with Redis

    10/12/2024 | NestJS

  • Building REST APIs with NestJS

    10/12/2024 | NestJS

  • Working with Databases using TypeORM in NestJS

    10/12/2024 | NestJS

Popular Category

  • Python
  • Generative AI
  • Machine Learning
  • ReactJS
  • System Design