Decoradores para Control de Acceso en Controladores NETJS

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

Resumen

¿Cómo proteger y hacer públicos los endpoints en NestJS?

NestJS ofrece una forma efectiva de proteger los endpoints utilizando guardianes y decoradores. Esto permite determinar programáticamente qué endpoints requieren autenticación y cuáles pueden ser públicos. En este artículo, exploraremos cómo utilizar estas funcionalidades en tus controladores de NestJS.

¿Cómo aplicar guardianes a los endpoints?

La protección de endpoints en NestJS se puede manejar mediante guardianes (guards). Los guardianes se aplican utilizando decoradores. Éstos permiten proteger todos los endpoints de un controlador al aplicar el decorador a nivel de clase. Esto significa que cualquier solicitud hacia un endpoint dentro de ese controlador deberá cumplir con las condiciones especificadas para ser autorizada.

@UseGuards(YourGuard)
export class YourController {
    // Todos los endpoints están protegidos
}

Este mecanismo a menudo utiliza un token de autorización en los headers de las solicitudes, como en el ejemplo donde se especifica que todos los endpoints requieren un header Authorization válido.

¿Cómo hacer un endpoint público usando setMetadata?

Para liberar un endpoint del control de un guardián, puedes usar la función setMetadata. Este decorador puede indicar que un endpoint específico es público y, por lo tanto, no necesita cumplir con las mismas restricciones.

Primero, importa SetMetadata desde el módulo @nestjs/common:

import { SetMetadata } from '@nestjs/common';

Luego, aplícalo al endpoint que deseas hacer público:

@Get('public-endpoint')
@SetMetadata('isPublic', true)
publicEndpoint() {
    // Este endpoint es público
}

El decorador @SetMetadata permite asignar metadata a un endpoint, especificando que es público. Así, a pesar de que el controlador esté protegido por un guardián, este específico endpoint quedará excluido de la restricción.

¿Cómo utilizar Reflector para leer metadata?

Para que un guardián ignore un endpoint, debe comprobar la metadata del endpoint en tiempo de ejecución. Esto se puede hacer mediante el uso del Reflector de NestJS, que permite acceder a la metadata definida en un endpoint.

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

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

    canActivate(context: ExecutionContext): boolean {
        const isPublic = this.reflector.get<boolean>('isPublic', context.getHandler());
        if (isPublic) {
            return true;  // Permitir acceso, ya que es un endpoint público
        }
        // Aplicar lógica de autorización normal
    }
}

¿Cómo crear un decorador personalizado para endpoints públicos?

Para evitar errores y mejorar la mantenibilidad, se recomienda crear un decorador personalizado que abrevie el uso de setMetadata. Este decorador se usa para marcar un endpoint específicamente como público.

  1. Crea un archivo para el decorador:
  2. Importa SetMetadata y define el decorador:
import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

Este decorador simplifica la declaración de un endpoint público y, al centralizar la clave de metadata, facilita cambios futuros.

¿Cómo aplicar el decorador personalizado en un controlador?

Una vez creado el decorador personalizado Public, se puede utilizar en cualquier controlador de manera sencilla:

@Get('new-endpoint')
@Public()
newEndpoint() {
    // Este endpoint ahora es público
}

Todo el flujo de autorización se mantiene en su sitio, y los desarrolladores pueden usar el decorador público para eximir endpoints específicos de la autorización en aplicaciones NestJS.

Recomendaciones para aplicar guardianes y decoradores

  • Consistencia: Usa el decorador personalizado siempre que sea posible para garantizar la coherencia en toda la base de código.
  • Pruebas exhaustivas: Antes de desplegar cambios, prueba tus endpoints para verificar que solo los que deben ser públicos lo son.
  • Documentación: Mantén documentación actualizada sobre qué endpoints están protegidos y cuáles no para evitar problemas de seguridad.

Con guardianes y decoradores personalizados, puedes manejar de manera eficiente la seguridad y accesibilidad de tus endpoints en NestJS. ¡Continúa explorando las poderosas capacidades de NestJS para crear aplicaciones robustas y seguras!