ガードの使用方法と認証の実装方法
NestJSのガード機能を理解し、認証の実装を行いましょう。
概要
NestJSには、リクエストの処理を続行するかどうかを決定するためのガードという機能が存在します。ガードはCanActivate
インターフェースを実装することで利用可能で、特に認証の処理によく用いられます。
ガードは主に以下の2つの役割を果たします。
- 認証: ユーザーの権限やロール、ACLの検証を行い、リクエストの処理を続行するかどうかを判定します。
- リクエストの制御: ミドルウェアとインターセプターの間で動作し、リクエストの処理を制御します。
この記事では、NestJSのガードの使用方法と、ガードを用いた認証の実装方法について解説します。
ガードの作成と利用
NestJSのCLIツールを使用してガードを作成することができます。以下のコマンドを実行すると、AuthGuard
という名前のガードが作成されます。
nest g guard users/guard/auth
作成されたガードは、CanActivate
インターフェースを実装しており、canActivate
メソッドを持っています。このメソッドは、リクエストの処理を続行するかどうかを決定するためのものです。
以下に、クエリパラメータが存在しない場合にリクエストを拒否するガードの例を示します。
/src/users/guard/auth/auth.guard.ts
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 !!request.query.params;
}
}
上記のコードでは、canActivate
メソッドがリクエストのクエリパラメータをチェックし、params
パラメータが存在する場合にのみリクエストの処理を続行します。
作成したガードを使用するには、@UseGuards
デコレータを使用してコントローラーまたはルートハンドラにバインドします。以下に例を示します。
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
HttpException,
HttpStatus,
UseFilters,
ParseIntPipe,
UseGuards,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
import { AuthGuard } from './guard/auth/auth.guard';
@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
getUsers(): User[] {
return this.usersService.getUsers();
}
@Post()
addUser(@Body() name: string): void {
this.usersService.addUser(name);
}
@Put(':id')
putUser(
@Param('id', ParseIntPipe) id: number,
@Body('name') name: string,
): void {
this.usersService.putUser(id, name);
}
@Delete(':id')
deleteUser(@Param('id', ParseIntPipe) id: number): void {
this.usersService.deleteUser(id);
}
@Get('throw')
getException(): string {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
@Get('custom_throw')
getCustomException(): string {
throw new ForbiddenException();
}
@Get('guard')
@UseGuards(AuthGuard)
getGuard(): string {
return 'Guard is working';
}
}
上記のコードでは、@UseGuards
デコレータを使用してAuthGuard
をgetHello
ルートハンドラにバインドしています。これにより、getHello
へのリクエストがあったときには、まずAuthGuard
のcanActivate
メソッドが実行され、その結果に基づいてリクエストの処理が続行されます。
テスト
## パラメーターがない場合通りません。
curl http://localhost:3000/users/guard
## パラメーターがある場合通ります。
curl http://localhost:3000/users/guard?params=true
まとめ
NestJSのガードは、リクエストの処理を続行するかどうかを決定する強力な機能です。特に、ユーザーの認証や権限の検証を行う際には、ガードを活用することで効率的に処理を行うことができます。ガードの使用方法を理解し、適切に活用していきましょう。