Що таке Guard?
Що таке Guard (гвард)
Guard (гвард) - це клас, який вирішує, чи можна виконати конкретний запит. Він перехоплює запит до того, як NestJS викличе контролер чи його метод.
Якщо Guard поверне
true→ запит проходить далі. Якщоfalseчи кидає виняток → запит блокується.
Таким чином, Guards - це фільтр рівня доступу. Вони схожі на middleware, але інтегровані глибше в життєвий цикл NestJS і працюють на рівні маршрутів, контролерів і модулів.
Інтерфейс Guard
Щоб створити Guard, потрібно реалізувати інтерфейс CanActivate
і визначити метод canActivate():
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
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. Локально (на рівні методу чи контролера):
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';
@Controller('users')
@UseGuards(AuthGuard) // застосовується до всіх методів
export class UsersController {
@Get()
findAll() {
return ['John', 'Alex'];
}
}Чи на один метод:
@Get('profile')
@UseGuards(AuthGuard)
getProfile() { ... }2. Глобально (для всього застосунку):
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:
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-перевіркою
@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).
Порядок:
Middleware → Guard → Interceptor (before) → Pipe → Controller → Interceptor (after)Guard з асинхронною логікою
Можна повернути Promise<boolean> чи Observable<boolean> - Nest це підтримує:
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 |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.