Guards

Intermedio
Nest
Nest
Actualizado: 15/06/2025

Introducción a los Guards

Los Guards en NestJS son una característica fundamental del sistema de seguridad que permite controlar el acceso a rutas y recursos específicos de tu aplicación. Funcionan como filtros de autorización que se ejecutan antes de que una petición llegue al controlador, determinando si debe procesarse o rechazarse.

Un Guard implementa la interfaz CanActivate y debe devolver un valor booleano que indica si la petición actual está autorizada para continuar. Esta decisión puede basarse en diversos factores como la autenticación del usuario, sus permisos, roles o cualquier lógica de negocio específica.

Funcionamiento básico de los Guards

Los Guards se ejecutan después de los middlewares pero antes de los interceptors y pipes. Esta posición en el ciclo de vida de la petición los convierte en el lugar ideal para implementar lógica de autorización, ya que pueden detener el procesamiento antes de que se ejecute cualquier lógica de negocio.

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();
    
    // Lógica de validación
    return this.validateRequest(request);
  }

  private validateRequest(request: any): boolean {
    // Ejemplo: verificar si existe un token de autorización
    return request.headers.authorization !== undefined;
  }
}

Tipos de Guards en NestJS

NestJS permite implementar diferentes tipos de Guards según las necesidades de tu aplicación:

Guards de autenticación: Verifican si el usuario está autenticado correctamente. Suelen validar tokens JWT, cookies de sesión o credenciales básicas.

@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    
    if (!token) {
      return false;
    }

    try {
      const payload = this.jwtService.verify(token);
      request.user = payload;
      return true;
    } catch {
      return false;
    }
  }

  private extractTokenFromHeader(request: any): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

Guards de autorización: Verifican si el usuario autenticado tiene los permisos necesarios para acceder a un recurso específico. Evalúan roles, permisos o políticas de acceso.

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<string[]>('roles', [
      context.getHandler(),
      context.getClass(),
    ]);

    if (!requiredRoles) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const user = request.user;

    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}

Aplicación de Guards

Los Guards pueden aplicarse a diferentes niveles de tu aplicación, proporcionando flexibilidad en el control de acceso:

A nivel global: Afecta a todas las rutas de la aplicación.

import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthGuard,
    },
  ],
})
export class AppModule {}

A nivel de controlador: Protege todas las rutas de un controlador específico.

@Controller('users')
@UseGuards(AuthGuard)
export class UsersController {
  @Get()
  findAll() {
    return 'Esta ruta está protegida por el AuthGuard';
  }
}

A nivel de método: Protege únicamente una ruta específica.

@Controller('users')
export class UsersController {
  @Get('profile')
  @UseGuards(AuthGuard, RolesGuard)
  getProfile() {
    return 'Ruta protegida por múltiples guards';
  }
}

ExecutionContext y acceso a datos

El ExecutionContext proporciona acceso completo a los detalles de la petición actual. Este contexto permite a los Guards examinar la petición HTTP, extraer headers, parámetros y cualquier información necesaria para tomar decisiones de autorización.

@Injectable()
export class OwnershipGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const resourceId = request.params.id;

    // Verificar si el usuario es propietario del recurso
    return this.checkOwnership(user.id, resourceId);
  }

  private checkOwnership(userId: string, resourceId: string): boolean {
    // Lógica para verificar propiedad del recurso
    return true; // Simplificado para el ejemplo
  }
}

Los Guards representan una herramienta esencial para implementar seguridad robusta en aplicaciones NestJS. Su integración natural con el sistema de inyección de dependencias permite crear soluciones de autorización complejas y reutilizables que se adaptan perfectamente a los requisitos de seguridad de aplicaciones empresariales.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Nest

Documentación oficial de Nest
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Nest es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Nest

Explora más contenido relacionado con Nest y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender qué son los Guards y su función en el ciclo de vida de una petición en NestJS.
  • Aprender a implementar Guards personalizados que controlen la autenticación y autorización.
  • Conocer los diferentes tipos de Guards y cuándo aplicarlos (autenticación, roles, propiedad).
  • Saber cómo aplicar Guards a nivel global, de controlador y de método.
  • Entender el uso de ExecutionContext para acceder a la información de la petición y tomar decisiones de seguridad.