Guards
Часть раздела TypeScript и NestJS путешествия по Node.js на Coddy. Урок 18 из 24.
Любой может создавать или удалять задачи. Страж решает, может ли запрос дойти до обработчика: Nest вызывает его canActivate, и если метод возвращает false, Nest отвечает кодом 403 «Доступ запрещён», не запуская метод.
@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() возвращает запрос; Node хранит имена его заголовков в нижнем регистре, поэтому читайте request.headers['x-api-key']. @UseGuards, указанный для метода, защищает этот метод. Указанный для класса контроллера, он защищает все методы этого класса.
Задание
ЛегкоСейчас любой может создавать и удалять задачи. Защитите два маршрута, изменяющих данные, с помощью API-ключа: секрета, который клиент отправляет в заголовке запроса. Чтение остается доступным всем.
- Откройте
src/common/api-key.guard.ts. В методеcanActivateклассаApiKeyGuardпрочитайте заголовокx-api-keyзапроса.context.switchToHttp().getRequest()возвращает запрос, а имена его заголовков всегда записываются строчными буквами. - Возвращайте
trueтолько если этот заголовок равенprocess.env.API_KEY, значение которого в этом уроке —tasks-key-123. Во всех остальных случаях возвращайтеfalse, в том числе если заголовок отсутствует. Когда guard возвращаетfalse, Nest отвечает кодом 403 и не запускает метод маршрута. - В
src/tasks/tasks.controller.tsимпортируйтеApiKeyGuardиз../common/api-key.guard, аUseGuards— из@nestjs/common. Добавьте@UseGuards(ApiKeyGuard)к методуcreate(POST /tasks) и методуremove(DELETE /tasks/:id). Не добавляйте его к классу: тогда будут заблокированы и маршруты GET. GET /tasks,GET /tasks/:idиGET /statsпродолжат работать без ключа.
Попробуйте: отправьте POST-запрос с { "title": "Buy milk" } на /tasks без заголовка. Вы получите 403:
{ "message": "Forbidden resource", "error": "Forbidden", "statusCode": 403 }Откройте поле Headers на панели запроса, добавьте строку x-api-key: tasks-key-123 и отправьте POST-запрос еще раз: получите 201 и новую задачу. С x-api-key: guess вы получите 403. Для DELETE /tasks/4 ключ тоже необходим: без него — 403, с ним — 204. GET /tasks работает вообще без заголовка.
Попробуйте сами
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
@Injectable()
export class ApiKeyGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
// Пропускайте запрос, только если его заголовок x-api-key
// совпадает с process.env.API_KEY.
return true;
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела TypeScript и NestJS
Потренируйтесь самостоятельно: Песочница Express