Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Guard?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Guard - клас, який вирішує, чи можна виконати конкретний запит: перехоплює запит до того, як NestJS викличе контролер, реалізує інтерфейс `CanActivate` з методом `canActivate()`, що повертає `true` (доступ дозволено) чи `false`/кидає виняток (доступ заборонено). **Ключове:** Guards виконуються після middleware, але до pipes і interceptors, і застосовуються на рівні методу, контролера чи глобально через `@UseGuards()` чи `app.useGlobalGuards()`; типове застосування - перевірка JWT, ролей і прав доступу.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке Guard (гвард) **Guard (гвард)** - це **клас, який вирішує, чи можна виконати конкретний запит**. Він **перехоплює запит до того, як NestJS викличе контролер чи його метод**. > Якщо Guard поверне `true` → запит проходить далі. > Якщо `false` чи кидає виняток → запит блокується. Таким чином, **Guards - це фільтр рівня доступу**. Вони схожі на middleware, але інтегровані глибше в життєвий цикл NestJS і працюють **на рівні маршрутів, контролерів і модулів**. ## Інтерфейс Guard Щоб створити Guard, потрібно реалізувати інтерфейс `CanActivate` і визначити метод `canActivate()`: ```javascript import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; @Injectable() export class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { // логіка перевірки return true; // чи false } } ``` ### Метод `canActivate()` - викликається **перед виконанням обробника маршруту**; - повертає: - `true` → доступ дозволено, - `false` → доступ заборонено, - або кидає виняток (`throw new UnauthorizedException()`). ## Приклад простого Guard ```javascript import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common'; @Injectable() export class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const authHeader = request.headers['authorization']; if (!authHeader || authHeader !== 'Bearer secret123') { throw new UnauthorizedException('Немає доступу'); } return true; // доступ дозволено } } ``` Цей Guard перевіряє наявність заголовка `Authorization`. Якщо токен неправильний - кидає помилку. ## Підключення Guard'а ### 1. Локально (на рівні методу чи контролера): ```javascript import { Controller, Get, UseGuards } from '@nestjs/common'; import { AuthGuard } from './auth.guard'; @Controller('users') @UseGuards(AuthGuard) // застосовується до всіх методів export class UsersController { @Get() findAll() { return ['John', 'Alex']; } } ``` Чи на один метод: ```javascript @Get('profile') @UseGuards(AuthGuard) getProfile() { ... } ``` ### 2. Глобально (для всього застосунку): ```javascript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { AuthGuard } from './auth.guard'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalGuards(new AuthGuard()); // глобальний гвард await app.listen(3000); } bootstrap(); ``` ## Що робить `ExecutionContext` `ExecutionContext` - це об'єкт, який дає доступ до поточного контексту виконання (HTTP, WebSocket, RPC). Приклад для HTTP: ```javascript canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); console.log(request.url); return true; } ``` Він дозволяє отримувати: - `request` і `response` для HTTP; - `data` і `context` для GraphQL; - `client` для WebSocket тощо. ## Приклад guard з JWT-перевіркою ```javascript @Injectable() export class JwtAuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const req = context.switchToHttp().getRequest(); const auth = req.headers['authorization']; if (!auth?.startsWith('Bearer ')) { throw new UnauthorizedException('Токен відсутній'); } const token = auth.split(' ')[1]; // тут могла б бути перевірка JWT if (token !== 'valid-token') { throw new UnauthorizedException('Невірний токен'); } return true; } } ``` ## Коли викликаються Guards Guards виконуються **перед пайпами (pipes)** і **інтерсепторами (interceptors)**. Порядок: ```javascript Middleware → Guard → Interceptor (before) → Pipe → Controller → Interceptor (after) ``` ## Guard з асинхронною логікою Можна повернути `Promise<boolean>` чи `Observable<boolean>` - Nest це підтримує: ```javascript async canActivate(context: ExecutionContext): Promise<boolean> { const request = context.switchToHttp().getRequest(); const isValid = await this.authService.validateToken(request.headers.authorization); return isValid; } ``` ## Коли варто використовувати Guards | Сценарій | Приклад | |---|---| | Автентифікація | Перевірка JWT, API-ключів, сесій | | Авторизація | Перевірка ролей користувача (`@Roles('admin')`) | | Доступ за умовою | Наприклад, "лише якщо заявка в статусі 'active'" | | Безпека маршрутів | Обмеження публічних/приватних API | ## Підсумок | Поняття | Опис | |---|---| | Guard (гвард) | Клас, який вирішує, чи можна обробити запит | | Інтерфейс | `CanActivate` | | Головний метод | `canActivate(context: ExecutionContext): boolean` | | Результат | `true` - пропустити, `false`/виняток - заблокувати | | Застосування | Перевірка прав, токенів, ролей, статусів | | Рівні застосування | Метод, контролер, глобально | | Порядок виконання | Після middleware, перед pipes/interceptors |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.