Simple and stateless JWT authentication flow in NestJS
Step 1: Install Dependencies
Simple and stateless JWT authentication flow in NestJS
Step 1: Install Dependencies
You’ll need the NestJS wrappers for Passport and JWT, along with the underlying Passport strategies.
npm install @nestjs/passport @nestjs/jwt passport passport-jwt
npm install -D @types/passport-jwt
Step 2: Configure the Auth Module
The AuthModule is where we configure how tokens will be signed. In a real application, you should use environment variables for your secret key.
// auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
PassportModule,
JwtModule.register({
secret: process.env.JWT_SECRET || 'super-secret-key',
signOptions: { expiresIn: '1h' }, // Tokens expire in 1 hour
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
})
export class AuthModule {}
Step 3: Implement the Auth Service
The AuthService is responsible for generating the JWT when a user successfully logs in.
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private jwtService: JwtService) {}
// In a real app, you would validate the password against the DB first
async login(user: any) {
const payload = { email: user.email, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
};
}
}
Step 4: Create the JWT Strategy
The Strategy acts as a middleware. It intercepts incoming requests, extracts the JWT from the Authorization: Bearer header, verifies the signature, and decodes the payload.
// jwt.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET || 'super-secret-key',
});
}
// This method runs ONLY if the token is valid and unexpired
async validate(payload: any) {
// What you return here is injected into the request object as `req.user`
return { userId: payload.sub, email: payload.email };
}
}
Step 5: Set Up the Auth Guard
Guards are the NestJS abstraction for protecting routes. Instead of typing @UseGuards(AuthGuard(‘jwt’)) everywhere, it is cleaner to create a custom class.
// jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Step 6: Protect Your Routes
Finally, tie it all together in your controller. We’ll simulate a login route to issue the token, and a protected route that requires it.
// auth.controller.ts
import { Controller, Post, Get, Body, Request, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtAuthGuard } from './jwt-auth.guard';
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@Post('login')
async login(@Body() loginDto: Record<string, any>) {
// Mock user verification — replace with your DB logic
const user = { id: 1, email: loginDto.email };
return this.authService.login(user);
}
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@Request() req) {
// req.user is populated by the return value of JwtStrategy.validate()
return req.user;
}
}
Security Note: JWTs are stateless, meaning a stolen token cannot easily be invalidated before it expires. Keep your expiresIn time relatively short (e.g., 15 minutes to 1 hour).
메타데이터
- post_id
- 7d9048ed072c
- slug
- simple-and-stateless-jwt-authentication-flow-in-nestjs-7d9048ed072c
- url
- https://medium.com/@ameenthilrash/simple-and-stateless-jwt-authentication-flow-in-nestjs-7d9048ed072c
- canonical_url
- https://medium.com/@ameenthilrash/simple-and-stateless-jwt-authentication-flow-in-nestjs-7d9048ed072c
- author_url
- https://medium.com/@ameenthilrash
- status
- ok
- fetched_at
- 2026-06-09 15:37:30