Menu
CoddyTech

Guards

Parte de la sección TypeScript y NestJS del Journey de Node.js de Coddy. Lección 18 de 24.

Cualquiera puede crear o eliminar tareas. Una guardia decide si una solicitud puede llegar a su manejador: Nest llama a su canActivate y, cuando devuelve false, Nest responde con 403 Prohibido sin ejecutar el método.

@Injectable()
export class OpenHoursGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        const hour = new Date().getHours();
        return hour >= 9 && hour < 17;
    }
}

@Post()
@UseGuards(OpenHoursGuard)
book() {}

context.switchToHttp().getRequest() proporciona la solicitud; Node almacena los nombres de sus encabezados en minúsculas, así que lee request.headers['x-api-key']. @UseGuards en un método protege ese método. En la clase del controlador, protege todos sus métodos.

challenge icon

Desafío

Fácil

En este momento, cualquiera puede crear o eliminar tareas. Protege las dos rutas que modifican datos con una clave API: un secreto que el cliente envía en el encabezado de una solicitud. La lectura sigue abierta para todos.

  1. Abre src/common/api-key.guard.ts. En el método canActivate de ApiKeyGuard, lee el encabezado x-api-key de la solicitud. context.switchToHttp().getRequest() te proporciona la solicitud, y los nombres de sus encabezados siempre están en minúsculas.
  2. Devuelve true solo cuando ese encabezado coincida con process.env.API_KEY, que en esta lección se establece en tasks-key-123. Devuelve false en cualquier otro caso, incluso si falta el encabezado. Cuando la guarda devuelve false, Nest responde con 403 y nunca ejecuta el método de la ruta.
  3. En src/tasks/tasks.controller.ts, importa ApiKeyGuard desde ../common/api-key.guard y UseGuards desde @nestjs/common. Coloca @UseGuards(ApiKeyGuard) en el método create (POST /tasks) y en el método remove (DELETE /tasks/:id). No lo coloques en la clase: eso también protegería las rutas GET.
  4. GET /tasks, GET /tasks/:id y GET /stats siguen funcionando sin una clave.

Pruébalo: envía POST con { "title": "Buy milk" } a /tasks sin ningún encabezado. Obtendrás 403:

{ "message": "Forbidden resource", "error": "Forbidden", "statusCode": 403 }

Abre el campo Headers de la barra de solicitudes, agrega la línea x-api-key: tasks-key-123 y vuelve a enviar el POST: obtendrás 201 y la nueva tarea. Con x-api-key: guess obtendrás 403. DELETE /tasks/4 también necesita la clave: 403 sin ella, 204 con ella. GET /tasks funciona sin ningún encabezado.

Pruébalo tú mismo

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

@Injectable()
export class ApiKeyGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        // Permite el paso de la solicitud solo cuando su encabezado x-api-key
        // sea igual a process.env.API_KEY.
        return true;
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de TypeScript y NestJS

Practica por tu cuenta: Playground de Express