Contenido del curso
Protección con guardianes
Autenticación con Passport
Autenticación con JSON Web Tokens
- 11

Implementación de JSON Web Tokens en APIs para Autenticación Segura
09:42 min - 12

Implementación de JWT en Módulo de Autenticación con Variables de Entorno
17:14 min - 13

Estrategia y Guardia de Autenticación con JWT en NestJS
16:38 min - 14

Extensión de Guardianes JWT en NestJS para Endpoints Públicos
12:39 min - 15

Control de Roles y Permisos con JSON Web Tokens en TypeScript
23:08 min - 16

Creación de Endpoints Seguros con JWT en NestJS
02:13 min
Deployment
- 17

Configuración y Despliegue de MongoDB Atlas en Heroku
06:23 min - 18

Configuración de Variables de Entorno en Heroku para MongoDB
16:25 min - 19

Configuración de PostgreSQL en Heroku para Node.js
07:32 min - 20

Configuración de Conexiones a Base de Datos en Heroku y Entorno Local
11:23 min - 21

Migraciones con TimeORM en Producción: Configuración y Ejecución
20:40 min
Próximos pasos
Decoradores para Control de Acceso en Controladores NETJS
Resumen
Controlar el acceso a los endpoints de una aplicación es fundamental, y en NestJS los guardianes ofrecen una forma elegante de hacerlo. Pero, ¿qué sucede cuando necesitas que ciertos endpoints sean públicos mientras el resto permanece protegido? La respuesta está en combinar guardianes con metadata y decoradores personalizados, logrando un código más flexible y mantenible.
¿Cómo proteger todos los endpoints de un controlador con un guardián?
Cuando se mueve el decorador @UseGuards() al nivel de la clase completa, todos los endpoints dentro de ese controlador quedan protegidos automáticamente [01:00]. Esto significa que cada ruta, ya sea getHello, newEndpoint o cualquier otra, requerirá cumplir con la validación definida en el guardián, por ejemplo, enviar un header de autorización con la API key correcta.
Sin embargo, en la práctica no siempre queremos que absolutamente todos los endpoints exijan autenticación. Algunos necesitan ser de acceso libre, y ahí es donde entra en juego la metadata.
¿Qué es setMetadata y cómo permite crear endpoints públicos?
El decorador setMetadata se importa desde @nestjs/common [02:25] y permite inyectar información adicional al contexto de un endpoint. Se usa de la siguiente manera:
- Se define un nombre para la metadata, por ejemplo
isPublic. - Se le asigna un valor, en este caso
true. - Se coloca como decorador sobre el método del controlador que se desea hacer público.
De esta forma, aunque el guardián se aplique a todo el controlador, los endpoints marcados con @SetMetadata('isPublic', true) podrán ser identificados como públicos.
¿Cómo lee el guardián la metadata del endpoint?
Para que el guardián pueda leer la metadata, se utiliza la clase Reflector, que se importa desde @nestjs/core [03:32]. Este servicio se inyecta en el constructor del guardián mediante inyección de dependencias:
typescript constructor(private reflector: Reflector) {}
Dentro del método canActivate, se obtiene el valor de la metadata así [04:05]:
typescript const isPublic = this.reflector.get<boolean>('isPublic', context.getHandler()); if (isPublic) { return true; }
- Si
isPublicestrue, el guardián retornatruedirectamente sin validar el header, permitiendo el acceso libre. - Si no existe esa metadata o es
false, se ejecuta la lógica habitual de validación del token.
Es importante que el nombre de la metadata coincida exactamente con el que se definió en el decorador; de lo contrario, el Reflector no podrá obtenerla.
¿Cómo se comportan las rutas públicas y protegidas?
Al probar en Insomnia [05:15], el resultado es claro:
- Los endpoints marcados como públicos responden sin necesidad de enviar ningún header.
- Los endpoints sin esa metadata devuelven un error de autorización si no se incluye el token válido.
- Al agregar el header correcto, los endpoints protegidos permiten el acceso normalmente.
¿Por qué crear un decorador personalizado para rutas públicas?
Usar @SetMetadata('isPublic', true) directamente tiene un riesgo: escribir mal el nombre de la metadata en algún punto del código. Para evitar este problema y hacer el código más mantenible, se recomienda crear un decorador personalizado [07:05].
Se crea un archivo dentro de una carpeta decorators en el módulo de autenticación, por ejemplo public.decorator.ts:
typescript import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic'; export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
- La constante
IS_PUBLIC_KEYcentraliza el nombre de la metadata en un solo lugar. - El decorador
@Public()encapsula la lógica deSetMetadatacon el valortruepor defecto.
En el guardián, se importa IS_PUBLIC_KEY desde el mismo archivo [09:10], reemplazando el string literal:
typescript const isPublic = this.reflector.get<boolean>(IS_PUBLIC_KEY, context.getHandler());
Ahora, en el controlador basta con usar @Public() sobre cualquier método que deba ser de acceso libre. Si el nombre de la key cambia en el futuro, solo se modifica en un lugar y todos los guardianes y controladores que la referencien se actualizan automáticamente.
Al probar nuevamente [09:55], el comportamiento es idéntico: las rutas marcadas con @Public() son de acceso libre, y el resto requiere el header de autorización. La ventaja real está en la mantenibilidad y la consistencia del código a lo largo de toda la aplicación.
¿Has implementado decoradores personalizados en tus proyectos con NestJS? Comparte tu experiencia y cuéntanos qué otros patrones te han resultado útiles.