Crea una cuenta o inicia sesi贸n

隆Contin煤a aprendiendo sin ning煤n costo! 脷nete y comienza a potenciar tu carrera

Adquiere por un a帽o todos los cursos, escuelas y certificados por un precio especial.

Antes: $249

Currency
$219/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Comprar ahora

Termina en:

0D
5H
46M
12S

Usando un decorador

5/22
Recursos

Aportes 3

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Comando para crear decorators:

nest g d auth/decorators/nombre --flat

Lo que hicimos

Esto aplica para ambos proyectos

Para proteger todo un controlador en lugar de solo una ruta en especifico, podemos asignarle el guard al controlador.

// src\app.controller.ts
...
@UseGuards(ApiKeyGuard)
@Controller()
...

Podemos crear un decorador para volver publico alguna ruta protegida.
Para ello, modificamos nuestro controlador

...
const isPublic = this.reflector.get('isPublic', context.getHandler());
    if (isPublic) {
      return true;
    }
const request = context.switchToHttp().getRequest<Request>();
    const authHeader = request.header('Auth');
    return authHeader === '1234';
  }

Creamos un decorador que nos facilite el envi贸 de metadata a la request

// src\auth\decorators\public.decortator.ts
import { SetMetadata } from '@nestjs/common'
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

Ahora podemos declara como publico alguna ruta protegida

@Public() // usando el decorador
  @Get('nuevo')
  newEndpoint() {
    return 'yo soy nuevo';
  }

Usando un decorador

Una funcionalidad muy 煤til a la hora de trabajar con nuestros guardianes es que en vez de nosotros tener que programar cual es la condici贸n que debe cumplir el contexto que necesitamos, lo que podemos hacer es usar decoradores que validen esta informaci贸n por nosotros:

Para nuestro ejemplo, lo que vamos a hacer es que vamos a proteger todos los Endpoints de nuestro controlador:

  • **src\app.controller.ts**:
// importamos el "SetMetadata"
import { Controller, Get, SetMetadata } from '@nestjs/common';

/* para que todos los enpoints de el controlador esten protegidos colocamos el 
decodador arriba del controlador */
// todos los endpoints estar谩n protegidos
@UseGuards(ApiKeyGuard)
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  // SetMetadata nos permite enviar metadatos que podemos recibir en el contexto del guardian
  @SetMetadata('isPublic', true)
  getHello(): string {
    return this.appService.getHello();
  }

  // ...
}

La forma en la que vamos a utilizar este metadato que estamos enviando al contexto del guardi谩n, en este caso va a ser para que con esa configuraci贸n protejamos todos los Endpoints del controlador, menos, el Endpoint que tenga el metadato **鈥榠sPiblic鈥** en **true**.

Veamos como:

  • **src/auth/guards/api-key.guard.ts**:
// importamos al reflector
import { Reflector } from '@nestjs/core';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  // debemos inyectar el reflector en nuestro guardian
  constructor(private reflector: Reflector) {}

  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    // con un m茅todo del reflector, nos traemos la metadata de "isPublic"
    // con el contexto, le indicamos que recibimos un manejador
    const isPublic = this.reflector.get('isPublic', context.getHandler());

    // el par谩metro tiene la propiedad "isPublic" como verdadera?
    if (isPublic) {
      // no hacemos validaci贸n
      return true;
    }

    // si en la metadata, indica que no es publico, hacemos la validaci贸n
    // ...
  }
}

De esta forma, si un par谩metro tiene en sus metadatos que es publico, no se realizar谩 la validaci贸n, pero si en sus metadatos no lo tienen, re debe realizar la validaci贸n.

Creando nuestros decoradores con metadatos

El crear nuestros propios decoradores con la metadata que necesitamos es 煤til para que no caigamos en errores de Typos, y tambi茅n tanto para agilizar la experiencia de desarrollo, como hacer el c贸digo mucho m谩s verboso.

Para realizar esto, vamos a crear este decorador de la siguiente forma:

  • **src\auth\decorators\public.decortator.ts**:
import { SetMetadata } from '@nestjs/common';

// instanciamos como queremos que se va a llamar la metadata
// lo exportamos por si lo queremos reutilizar en otro decodador y en el guardian
export const IS_PUBLIC_KEY = 'isPublic';

// creamos el decorador primero como una funci贸n flecha
// va a ser igual al decodador "SetMetadata", pero con el metadato "isPublic" como "true"
export const IsPublic = () => SetMetadata(IS_PUBLIC_KEY, true);

Y ahora solo tendr铆amos que usar este decorador de la siguiente forma:

  • **src\app.controller.ts**:
// importamos nuestro decoador
import { IsPublic } from './auth/decorators/public.decorator';

@UseGuards(ApiKeyGuard)
@Controller()
export class AppController {

  @Get()
  // lo usamos en el par谩metro deseado
  @IsPublic()
  getHello(): string {
    return this.appService.getHello();
  }
}

Y listo, ahora tenemos un decorador un poco m谩s flexible y personalizado.