メインコンテンツまでスキップ

7. Guards

ガードの役割

ガードは、リクエストが特定の条件を満たしているかを検証するために使用されます。主に認証と認可のロジックを実装するために使用されます。ガードは、コントローラーまたはルートハンドラーの前に実行され、リクエストが処理される前にアクセス制御を行います。

基本的な使用方法

新しいガードを作成するには、@Injectableデコレーターを使用してクラスを定義し、CanActivateインターフェースを実装します。

基本的なガードの例

以下は基本的なガードの例です:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}

validateRequest(request: any): boolean {
// 認証ロジックをここに追加
return true;
}
}

ガードの登録

ガードをコントローラーまたは特定のハンドラに適用するには、@UseGuardsデコレーターを使用します。

import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';

@Controller('cats')
export class CatsController {
@Get()
@UseGuards(AuthGuard)
findAll(): string {
return 'This action returns all cats';
}
}

グローバルガード

アプリケーション全体にガードを適用する場合は、グローバルガードとして登録します。

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();

カスタムガードの実装例

ロールベースのアクセス制御

以下はユーザーのロールに基づいてアクセスを制御するカスタムガードの例です:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}

canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return this.matchRoles(roles, user.roles);
}

matchRoles(roles: string[], userRoles: string[]): boolean {
return roles.some(role => userRoles.includes(role));
}
}

コントローラーでロールベースのアクセス制御を使用するには、@SetMetadataデコレーターを使用してロールを定義します。

import { Controller, Get, UseGuards, SetMetadata } from '@nestjs/common';
import { RolesGuard } from './roles.guard';

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {
@Get()
@SetMetadata('roles', ['admin'])
findAll(): string {
return 'This action returns all cats';
}
}

JWT認証ガード

以下はJWT(JSON Web Token)を使用した認証ガードの例です:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private readonly authService: AuthService, private readonly jwtService: JwtService) {}

async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization;
if (!token) {
return false;
}
return this.validateToken(token);
}

async validateToken(token: string): Promise<boolean> {
try {
const decoded = this.jwtService.verify(token);
return !!decoded;
} catch (err) {
return false;
}
}
}

これで、ガードの基本的な役割と使用方法について理解できました。次のセクションでは、インターセプターの役割と使用方法について説明します。