NestJS is an extensible framework for building server-side applications using TypeScript. One of its key features is the ability to implement guards, which provide a way to intercept and control the flow of incoming requests to routes. Guards are used to implement authorization logic, ensuring that only authorized users can access certain routes. This article will explore how to create and use guards in NestJS to protect routes effectively.
What are Guards?
In NestJS, guards are classes that implement the CanActivate interface. They determine whether a request should be handled by the route handler or not. Guards are typically used for authentication and authorization purposes, but they can also be used for other use cases like request validation.
How do Guards work?
Guards are executed before the route handler and can perform any necessary checks to decide if the request is allowed to proceed. They return a boolean value, a promise that resolves to a boolean, or an observable that emits a boolean. If the value is true, the request proceeds; otherwise, it is blocked.
Steps to Create Guards
Step 1: Install the nestjs cli
npm i -g @nestjs/cliStep 2: Create a NestJS project
nest new nest-gfg
cd nestgfg
Step 3: Create a guard using the following command.
nest generate guard guards/authFolder Structure
Dependencies
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/mongoose": "^10.0.10",
"@nestjs/platform-express": "^10.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
}
Example: Implementing Guards while accessing a specific route.
// src/guards/auth/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}
validateRequest(request: any): boolean {
// Add your authentication logic here
const authHeader = request.headers.authorization;
return authHeader && authHeader === 'Bearer my-secret-token';
}
}
// src/app.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './guards/auth/auth.guard';
@Controller()
export class AppController {
@Get('protected')
@UseGuards(AuthGuard)
getProtectedResource(): string {
return 'This is a protected resource';
}
@Get()
getPublicResource(): string {
return 'This is a public resource';
}
}
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
imports: [],
controllers: [AppController],
providers: [],
})
export class AppModule { }
To start the application run the following command.
npm run start