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.
Desafío
FácilEn 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.
- Abre
src/common/api-key.guard.ts. En el métodocanActivatedeApiKeyGuard, lee el encabezadox-api-keyde la solicitud.context.switchToHttp().getRequest()te proporciona la solicitud, y los nombres de sus encabezados siempre están en minúsculas. - Devuelve
truesolo cuando ese encabezado coincida conprocess.env.API_KEY, que en esta lección se establece entasks-key-123. Devuelvefalseen cualquier otro caso, incluso si falta el encabezado. Cuando la guarda devuelvefalse, Nest responde con 403 y nunca ejecuta el método de la ruta. - En
src/tasks/tasks.controller.ts, importaApiKeyGuarddesde../common/api-key.guardyUseGuardsdesde@nestjs/common. Coloca@UseGuards(ApiKeyGuard)en el métodocreate(POST /tasks) y en el métodoremove(DELETE /tasks/:id). No lo coloques en la clase: eso también protegería las rutas GET. GET /tasks,GET /tasks/:idyGET /statssiguen 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;
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de TypeScript y NestJS
1Fundamentos de Nest
Clases y métodosHola, NestRegistro de un controlador4Guards, filtros e interceptores
GuardsPractica por tu cuenta: Playground de Express