Guard는 요청이 라우트 핸들러로 진행될 수 있는지 결정합니다 — 인가(그리고 종종 인증 확인)를 위한 NestJS의 전용 메커니즘입니다. Guard는 요청을 허용하려면 true를, 차단하려면 false를 반환하거나 예외를 던집니다.
기본 guard
()
{
(: ): {
request = context.().();
!!request..;
}
}
Guard는 canActivate()를 구현하며, 이는 boolean(또는 그것의 Promise/Observable)을 반환합니다. false를 반환하면 403으로 요청을 차단합니다. 특정 예외(예: UnauthorizedException)를 던질 수도 있습니다.
@UseGuards(AuthGuard) // 단일 라우트에
@Get("profile")
getProfile() {}
@UseGuards(AuthGuard) // 전체 controller에 (모든 라우트)
@Controller("admin")
export class AdminController {}
app.useGlobalGuards(new AuthGuard()); // 전역으로 (모든 라우트)
Guard는 메서드, controller, 전역 수준에서 적용할 수 있습니다.
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization?.split(" ")[1];
if (!token) throw new UnauthorizedException();
try {
request.user = await this.jwtService.verifyAsync(token); // 사용자 부착
return true;
} catch {
throw new UnauthorizedException("Invalid token");
}
}
}
// @Roles decorator가 필요한 역할을 메타데이터로 저장
@Roles("admin")
@Get("users")
listUsers() {}
// RolesGuard가 메타데이터를 읽어 사용자의 역할을 확인
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(ctx: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>("roles", ctx.getHandler());
const { user } = ctx.switchToHttp().getRequest();
return roles.some(role => user.roles?.includes(role)); // 필요한 역할이 있으면 허용
}
}
@Roles() decorator(메타데이터)와 그것을 읽는 guard(Reflector를 통해)를 결합하는 것은 역할 기반 접근 제어의 표준 패턴입니다.
ExecutionContext는 guard에게 풍부한 정보(핸들러, 클래스, request)를 제공합니다 —
일반 middleware보다 많습니다 — 이것이 (middleware가 아닌) guard가 인가 결정에
적합한 위치인 이유입니다.
Guard는 인가를 위한 전용의 관용적인 NestJS 메커니즘입니다 — 인증과 권한에 기반하여 어떤 요청이 핸들러에 도달할 수 있는지 제어합니다.
거의 모든 실제 애플리케이션이 라우트를 보호해야 하므로(로그인 요구, 역할/권한 확인) 이를 이해하는 것이 필수적이며, guard는 이를 위한 올바른 도구입니다(인증 로직을 middleware나 각 핸들러에 욱여넣는 것보다 훨씬 깔끔함).
표준 패턴 — 자격 증명을 검증하고 사용자를 request에 부착하는 JWT/인증 guard, 그리고 RBAC를 위해 @Roles() decorator와 Reflector를 읽는 guard를 결합한 역할 기반 guard — 은 NestJS API를 보호하는 데 기본적입니다.
Guard가 풍부한 ExecutionContext(대상 핸들러, 클래스, request를 앎)에 접근하는 것이 바로 middleware가 깔끔하게 내릴 수 없는 인가 결정에 적합하게 만드는 요소입니다.
Guard를 작성하고, 적용하고(메서드/controller/전역), 메타데이터 decorator와 결합하는 방법을 아는 것은 보안이 적용된 NestJS 애플리케이션을 구축하는 핵심 지식이며 프레임워크에서 자주 다뤄지는 아키텍처적으로 중요한 주제입니다.