How to Use @UseGuards in NestJS for Route Protection
In NestJS, use the
@UseGuards decorator to apply guard classes that control access to routes or controllers. Guards run before route handlers and decide if the request should proceed based on custom logic like authentication or roles.Syntax
The @UseGuards decorator accepts one or more guard classes as arguments and applies them to a controller or route handler. Guards must implement the CanActivate interface with a canActivate() method that returns true to allow access or false to deny it.
Example parts:
@UseGuards(AuthGuard): Applies theAuthGuardto protect the route.canActivate(context: ExecutionContext): boolean | Promise: Method that contains the guard logic.
typescript
import { UseGuards, CanActivate, ExecutionContext } from '@nestjs/common'; class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { // Your guard logic here return true; // or false } } @UseGuards(AuthGuard) class SomeController { // routes here }
Example
This example shows a simple ApiKeyGuard that allows access only if a custom header x-api-key matches a secret key. The @UseGuards decorator applies this guard to a route, protecting it from unauthorized requests.
typescript
import { Controller, Get, UseGuards, ExecutionContext, CanActivate } from '@nestjs/common'; class ApiKeyGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const apiKey = request.headers['x-api-key']; return apiKey === 'secret123'; } } @Controller('data') export class DataController { @Get() @UseGuards(ApiKeyGuard) getData() { return { message: 'Access granted to protected data' }; } }
Output
{"message":"Access granted to protected data"}
Common Pitfalls
- Forgetting to implement
CanActivateinterface causes the guard not to work. - Not returning
trueorfalseexplicitly fromcanActivateleads to unexpected behavior. - Applying
@UseGuardswithout importing or providing the guard class in the module causes runtime errors. - Using
@UseGuardson a controller applies the guard to all routes inside it, which might be unintended.
typescript
/* Wrong: Missing CanActivate implementation */ class WrongGuard { canActivate() { return true; } } /* Right: Implements CanActivate */ import { CanActivate, ExecutionContext } from '@nestjs/common'; class RightGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { return true; } }
Quick Reference
Use @UseGuards(GuardClass) to protect routes. Guards must implement CanActivate and return true or false. Apply guards at method or controller level. Remember to provide guards in your module.
| Concept | Description |
|---|---|
| @UseGuards | Decorator to apply one or more guards to routes or controllers |
| CanActivate | Interface guards implement with canActivate() method |
| canActivate() | Returns true to allow or false to deny route access |
| Apply at method | Protects a single route handler |
| Apply at controller | Protects all routes in the controller |
| Provide guard | Add guard class to module providers for injection |
Key Takeaways
Use @UseGuards with guard classes implementing CanActivate to protect routes.
The canActivate method must return true to allow or false to deny access.
Apply guards at controller or route level depending on scope needed.
Always provide guard classes in the module to avoid runtime errors.
Test guards carefully to ensure they block or allow requests as intended.