Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Introducción a Guards

4/22
Recursos

Aportes 6

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Por si alguno tiene dudas sobre qué se puede hacer una vez el proyecto esté completado…
Les dejo un proyecto propio de fake ecommerce que usa como base esta API (tiene modificaciones y detalles para adaptarla a mi proyecto). El frontend está hecho con React
Link aquí
Saludos a todos

Lo que hicimos

Esto aplica para ambos proyectos

nest g mo auth
nest g gu auth/guards/apiKey --flat

Configuración del guard

import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Request } from 'express';

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const authHeader = request.header('Auth');
    const isAuth = authHeader === '1234';
    if (!isAuth) {
      throw new UnauthorizedException('not allow');
    }
    return true;
  }
}

Protegiendo una ruta

@UseGuards(ApiKeyGuard)
  @Get('nuevo')
  newEndpoint() {
    return 'yo soy nuevo';
  }

me gustan las clases de Nicolas, pero esta nueva metodología de retomar código de otros cursos no.

4 artefactos principales en el framework


Controllers

Providers

Pipes

Guards


Los Guards nos ayudarán a brindar cada uno de los endpoints en el controller, y nos dirá si tiene o no autorización.


Ejecutamos nest g mo auth para crear un módulo nuevo, y generamos el guard con nest g gu auth/guards/apiKey —flat

Por cierto, el @UseGuard( … ) hay que importarlo de
import { …, UseGuards } from ‘@nestjs/common’;

Error usando guards y @Res en el mismo Endpoint
Quiero compartir un error que tuve al estar usando un guard y @Res en el mismo endpoint.

Guard

@Injectable()
export class ApiKeyGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const authHeader = request.header('auth') || '';
    if (authHeader !== '123456') {
      throw new UnauthorizedException('User Unathorized');
    }
    return true;
  }
}

Controller


  @HttpCode(HttpStatus.ACCEPTED) 
  @Get('new')
  @UseGuards(ApiKeyGuard)
  newEndpoint(@Res() res: Response) {
    return res.json({ message: 'new world!' });
  }

Según mi teoría al estar usando el mismo request en el guard y el controller causaba este error

Error: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
node_app_dev  | Please open an issue with this stack trace at https://github.com/nodejs/node/issues
node_app_dev  | 
node_app_dev  |     at new NodeError (node:internal/errors:387:5)
node_app_dev  |     at assert (node:internal/assert:14:11)
[3:22:57 PM] File change detected. Starting incremental compilation...
[3:23:13 PM] File change detected. Starting incremental compilation...

Y se soluciono simplmente cambiando la forma de la respuesta en el controller

  @HttpCode(HttpStatus.ACCEPTED) // 👈 Using decorator
  @Get('new')
  @UseGuards(ApiKeyGuard)
  newEndpoint() {
    return { message: 'new world!' };
  }

Por defecto la respuesta se manda como JSON así que no es necesario usar res.json().

Vengo de express y por eso estaba tratando de usar esa misma forma.