0
0
NestjsHow-ToBeginner ยท 3 min read

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 the AuthGuard to 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 CanActivate interface causes the guard not to work.
  • Not returning true or false explicitly from canActivate leads to unexpected behavior.
  • Applying @UseGuards without importing or providing the guard class in the module causes runtime errors.
  • Using @UseGuards on 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.

ConceptDescription
@UseGuardsDecorator to apply one or more guards to routes or controllers
CanActivateInterface guards implement with canActivate() method
canActivate()Returns true to allow or false to deny route access
Apply at methodProtects a single route handler
Apply at controllerProtects all routes in the controller
Provide guardAdd 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.