Skip to main content

Що таке Guard?

Що таке 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
MiddlewareGuardInterceptor (before)PipeControllerInterceptor (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

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.