How to Implement Authentication in NestJS: Simple Guide
To implement authentication in
NestJS, use the @nestjs/passport package with strategies like JWT. Set up a guard with AuthGuard to protect routes and use services to validate users and generate tokens.Syntax
Authentication in NestJS typically involves these parts:
- AuthModule: Imports and configures Passport and JWT modules.
- AuthService: Handles user validation and token creation.
- Strategy: Defines how to validate tokens or credentials (e.g., JWT strategy).
- AuthGuard: Protects routes by checking authentication.
typescript
import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { PassportModule } from '@nestjs/passport'; import { AuthService } from './auth.service'; import { JwtStrategy } from './jwt.strategy'; @Module({ imports: [ PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule.register({ secret: 'yourSecretKey', signOptions: { expiresIn: '60m' }, }), ], providers: [AuthService, JwtStrategy], exports: [AuthService], }) export class AuthModule {} // AuthGuard usage example import { Controller, Get, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Controller('profile') export class ProfileController { @UseGuards(AuthGuard('jwt')) @Get() getProfile() { return { message: 'This is a protected route' }; } }
Example
This example shows a simple JWT authentication setup in NestJS. It includes user validation, token generation, and a protected route.
typescript
import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; @Injectable() export class AuthService { private users = [{ id: 1, username: 'user', password: 'pass' }]; constructor(private jwtService: JwtService) {} async validateUser(username: string, pass: string) { const user = this.users.find(u => u.username === username && u.password === pass); if (user) { const { password, ...result } = user; return result; } return null; } async login(user: any) { const payload = { username: user.username, sub: user.id }; return { access_token: this.jwtService.sign(payload), }; } } @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: 'yourSecretKey', }); } async validate(payload: any) { return { userId: payload.sub, username: payload.username }; } } import { Controller, Post, Request, UseGuards, Get } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Controller() export class AppController { constructor(private authService: AuthService) {} @Post('login') async login(@Request() req) { const user = await this.authService.validateUser(req.body.username, req.body.password); if (!user) { return { message: 'Invalid credentials' }; } return this.authService.login(user); } @UseGuards(AuthGuard('jwt')) @Get('protected') getProtected() { return { message: 'You accessed a protected route' }; } }
Output
{ "access_token": "<jwt_token_here>" }
{ "message": "You accessed a protected route" }
Common Pitfalls
Common mistakes when implementing auth in NestJS include:
- Not setting the JWT secret consistently in
JwtModuleandJwtStrategy. - Forgetting to add
@UseGuards(AuthGuard('jwt'))on protected routes. - Not validating user credentials properly before issuing tokens.
- Using synchronous code where async is expected, causing unexpected behavior.
typescript
/* Wrong: Missing @UseGuards on protected route */ @Controller('data') export class DataController { @Get() getData() { return { secret: 'data' }; } } /* Right: Protect route with AuthGuard */ @Controller('data') export class DataController { @UseGuards(AuthGuard('jwt')) @Get() getData() { return { secret: 'data' }; } }
Quick Reference
Remember these key points for NestJS auth:
- Use
@nestjs/passportand@nestjs/jwtpackages. - Configure
JwtModulewith a secret and expiration. - Create a
JwtStrategyto validate tokens. - Protect routes with
@UseGuards(AuthGuard('jwt')). - Validate users before issuing JWT tokens.
Key Takeaways
Use Passport and JWT modules to implement authentication in NestJS.
Protect routes with AuthGuard using the 'jwt' strategy.
Always validate user credentials before issuing JWT tokens.
Keep your JWT secret consistent across modules and strategies.
Use async methods properly to avoid authentication errors.