Authentication with NestJS

Jul 2, 2024

Authentication with NestJS

Overview

In this lecture, we will cover various aspects of implementing authentication in a NestJS application. This includes setting up sign-up, login, and refresh token endpoints, generating access and refresh tokens, and using guards for protecting routes.

Project Setup

  • Basic NestJS Application
    • Listening on Port 3000.
  • Generate Resources
    • Create a nor module.
    • Create schemas and dto folders.
  • Installing Dependencies
    • Mongoose: npm install @nestjs/mongoose mongoose
    • Class Validator: npm install class-validator class-transformer
    • Bcrypt: npm install bcrypt @types/bcrypt
    • UUID: npm install uuid
    • NestJS JWT: npm install @nestjs/jwt
    • NestJS Config: npm install @nestjs/config

Creating Schemas

  • User Schema
    • Defined with @Schema decorator.
    • Properties: name, email (unique), and password.

DTO (Data Transfer Object)

  • Signup DTO
    • Fields: name, email, password.
    • Class validators: Ensures data validation and constraints.
  • Login DTO
    • Fields: email, password.

Validation Pipe

  • Apply global validation pipe in main.ts.
  • Configuration: whitelist: true, forbidNonWhitelisted: true.

Setting Up Mongoose

  • Configure MongoDB connection in app.module.ts using MongooseModule.forRoot().
  • Import user model into nor.module.ts using MongooseModule.forFeature().
  • Inject user model into AuthService.

Signup Endpoint

  • Controller Setup
    • Create route: @Post('signup').
    • Method: async signup(@Body() signupData: SignupDto).
  • Service Method
    • Check if email exists, hash password with bcrypt, save user.
    • Hashing password: bcrypt.hash(password, 10) (salt rounds = 10).

Login Endpoint

  • Controller Setup
    • Create route: @Post('login').
    • Method: async login(@Body() credentials: LoginDto).
  • Service Method
    • Check if email exists, compare passwords with bcrypt.
    • Generate access and refresh tokens using jsonwebtoken.

JWT Configuration

  • Default Configuration
    • Secret: Store securely (e.g., in environment variables).
    • Modules: JwtModule in app.module.ts.
  • Token Generation
    • Access Token: Short-lived, includes userId in payload, set expiry (e.g., 1h).
    • Refresh Token: Long-lived, needs to be saved in the database.

Creating and Storing Refresh Tokens

  • Schema: RefreshTokenSchema
    • Properties: token, userId, expiryDate.
  • Service Method
    • Generate token with uuidv4(), store in database.
    • Expiry: Current date + 3 days.

Refresh Token Endpoint

  • Controller Setup
    • Create route: @Post('refresh').
    • Method: async refreshTokens(@Body() refreshTokenDto: RefreshTokenDto).
  • Service Method
    • Verify token existence and non-expiry, generate new tokens.

Guards for Route Protection

  • Custom Guard
    • Class: AuthGuard implements CanActivate.
    • Import JwtService, verify token from headers.
    • Check token validity, attach user info to request object.
    • Apply guard at the controller or route level.

Unauthorized and Error Handling

  • Controller Return Values
    • For invalid/expired tokens, throw UnauthorizedException.
  • Error Logging
    • Log errors for troubleshooting (e.g., JWT expired messages).

Testing and Debugging

  • Tools: Postman for API testing.
  • Timestamps and Expiry
    • Monitor token expiry, validate error handling for expired tokens.

Conclusion

  • Summary
    • Implemented user signup and login with JWT-based authentication.
    • Created access and refresh tokens, and guarded routes using custom guards.
  • Next Steps
    • Future videos on changing passwords, resetting passwords via email, roles and permissions.
  • Resources
    • Links to NestJS playlist and related videos for more in-depth understanding.

Feel free to refer back to these notes for a high-level overview and key implementation details from the lecture on NestJS authentication.