Creación y Uso de Guardianes en NestJS para Autorización de Endpoints

Clase 4 de 22Curso de NestJS: Autenticación con Passport y JWT

Resumen

¿Qué son los guardianes en NestJS y cómo funcionan?

Los guardianes son uno de los componentes más importantes en el framework NestJS, junto con los controladores, proveedores y pipes. Estos elementos son cruciales para asegurar que cada endpoint de un controlador tenga o no la autorización necesaria. En esencia, los guardianes permiten validar cualquier tipo de información que venga en los headers, como tokens de API, o cualquier otro estado requerido, antes de conceder acceso a un recurso solicitado.

¿Cómo crear y estructurar un guardián?

Para crear un guardián, primero se debe crear un módulo específico para manejar la autenticación dentro de la aplicación. Independientemente del proyecto en el que te encuentres, ya sea Mongo o cualquier otro, el proceso inicia con la generación de un nuevo módulo que administrará la autenticación. Dentro de este módulo, utilizaremos el generador de NestJS para crear un guardián.

nest generate guard guardianes/apk --skipTests

Aquí estamos indicando al generador que cree un guardián llamado apk dentro de una carpeta específica llamada guardianes.

Explorando el guardián generado

El guardián generado por defecto incluye un método que se encarga de decidir si se concede el acceso o no. Este método puede regresar un valor booleano, una promesa que regrese un booleano, o un observable, dependiendo de la implementación:

canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
  return true; // true para permitir acceso, false para denegarlo
}

Configurando el guardián en un controlador

Para proteger un endpoint, primero importamos el guardián en el controlador correspondiente:

import { UseGuards } from '@nestjs/common';
import { Apkguarian } from './guardianes/apk.guard';

@Controller('api')
export class AppController {
  @Get('nuevo')
  @UseGuards(Apkgurar)
  nuevo() {
    return 'Acceso concedido';
  }
}

Ahora, el endpoint nuevo está protegido por el guardián, el cual por defecto no permite el acceso, simulando un valor false.

Validación dinámica con headers

Supongamos que queremos otorgar acceso solo si un header específico está presente en la solicitud. Para esto, implementamos la lógica necesaria en el método canActivate:

canActivate(context: ExecutionContext): boolean {
  const request = context.switchToHttp().getRequest();
  const authHeader = request.headers['authorization'];

  if (authHeader === '1234') {
    return true;
  } else {
    throw new UnauthorizedException('No estás autorizado');
  }
}

Este código revisa si el header authorization tiene el valor 1234 antes de permitir el acceso.

Probando en Insomnia

Si probamos con Insomnia o cualquier cliente REST, observa que cuando el header authorization tiene el valor correcto, se concede el acceso. De lo contrario, se lanza una excepción indicando que el acceso no está autorizado.

::tip:: Consejo: Personaliza los mensajes de error para que sean más claros y comprensibles. Usar excepciones específicas como UnauthorizedException en NestJS facilita esta tarea.

Aprender sobre los guardianes y cómo aplicarlos en tus proyectos es fundamental para tener una aplicación NestJS segura y robusta. Experimenta con diferentes condiciones y mecanismos de validación, y sigue aprendiendo sobre cómo mejorar la seguridad en tus aplicaciones. ¡Sigue adelante y no te detengas!