Guard란?
Guard는 쉽게 말해서 인증(Authentication)과 권한 부여(Authorization)를 처리하는 데 사용됩니다.
가드와 CanActivate 인터페이스
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly authService: AuthService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization;
return this.authService.validateToken(token);
}
}
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class RolesGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
const user = request.user;
return user && user.role === 'admin'; // 사용자 역할이 'admin'인 경우에만 접근 허용
}
}
가드는 CanActivate 인터페이스를 구현하는 클래스로 정의해 작성합니다.
위처럼 인증과 권한부여를 CanActivate 클래스를 이용해 작성합니다.
import { Controller, Get, UseGuards } from '@nestjs/common';
@Controller('admin')
@UseGuards(AuthGuard, RolesGuard) // AuthGuard와 RolesGuard를 함께 적용
export class AdminController {
@Get()
findAll() {
return 'This action returns all admin resources';
}
}
위처럼 Admin 권한을 부여받은 로그인한 유저만 해당 API에 접근할 수 있게 작성할 수 있습니다.
@UseGuards 데코레이터는 특정 라우트 핸들러나 컨트롤러에 가드를 적용하는 데 사용됩니다.
이 데코레이터는 내부적으로 NestJS의 DI 컨테이너를 사용하여 가드의 인스턴스를 생성하고, 라우트가 호출될 때 해당 인스턴스의 canActivate 메서드를 호출합니다.
동작방식
1. 가드 정의: 가드는 클래스 수준에서 정의되며, CanActivate 인터페이스를 구현합니다.
2. 가드 주입: 가드 클래스는 @Injectable() 데코레이터를 통해 DI 컨테이너에 주입될 수 있게 합니다. 이는 서비스, 컨트롤러, 모듈 등과 동일한 방식으로 작동합니다.
3. @UseGuards 데코레이터 적용: 특정 컨트롤러나 라우트 핸들러에 가드를 적용합니다.
4. DI 컨테이너 사용: 라우트가 호출될 때, NestJS는 DI 컨테이너를 사용하여 가드의 인스턴스를 생성하고, 해당 인스턴스의 canActivate 메서드를 호출하여 요청을 처리할 수 있는지 확인합니다.
사용자 정의 메타데이터 설정
사용자 정의 메타데이터(custom metadata)는 특정 핸들러나 클래스에 대해 추가 정보를 제공하기 위해 사용됩니다.
이러한 메타데이터는 NestJS의 반사(reflection) 기능을 통해 접근할 수 있으며, 이를 활용하여 다양한 동작을 정의하거나 제어할 수 있습니다.
NestJS에서는 @SetMetadata() 데코레이터를 사용하여 사용자 정의 메타데이터를 설정할 수 있습니다.
이 메타데이터는 특정 핸들러나 클래스에 부착되며, Reflector를 통해 나중에 읽을 수 있습니다.
1. 역할 정의
먼저, 역할을 정의하는 enum을 작성합니다.
export enum Role {
User = 'user',
Admin = 'admin',
}
2. 역할 데코레이터 작성
다음으로, 역할을 설정하는 데 사용할 커스텀 데코레이터를 작성합니다.
이 데코레이터는 @SetMetadata()를 사용하여 메타데이터를 설정합니다.
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: Role[]) => SetMetadata('roles', roles);
3. 역할 가드 작성
이제 역할 기반 접근 제어를 구현할 가드를 작성합니다.
이 가드는 실행 컨텍스트와 Reflector를 사용하여 메타데이터를 읽고 검증합니다.
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Role } from './role.enum';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<Role[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return roles.some((role) => user.roles?.includes(role));
}
}
4. 컨트롤러에 역할 데코레이터 적용
이제 특정 핸들러에 역할 데코레이터를 적용할 수 있습니다.
import { Controller, Get, Post, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
import { Role } from './role.enum';
@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {
@Get()
@Roles(Role.User)
findAll() {
return ['This action returns all cats'];
}
@Post()
@Roles(Role.Admin)
create() {
return 'This action adds a new cat';
}
}
참고
Guard
https://docs.nestjs.com/guards
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
사용자 정의 권한 부여
https://docs.nestjs.com/security/authorization
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
'JaveScript > NestJS' 카테고리의 다른 글
예외 필터 (0) | 2024.06.13 |
---|---|
Middleware (0) | 2024.06.11 |
@Module() (0) | 2024.06.10 |
Provider (0) | 2024.06.09 |
@Body() 데코레이터 (1) | 2024.06.08 |
Guard란?
Guard는 쉽게 말해서 인증(Authentication)과 권한 부여(Authorization)를 처리하는 데 사용됩니다.
가드와 CanActivate 인터페이스
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly authService: AuthService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization;
return this.authService.validateToken(token);
}
}
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class RolesGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
const user = request.user;
return user && user.role === 'admin'; // 사용자 역할이 'admin'인 경우에만 접근 허용
}
}
가드는 CanActivate 인터페이스를 구현하는 클래스로 정의해 작성합니다.
위처럼 인증과 권한부여를 CanActivate 클래스를 이용해 작성합니다.
import { Controller, Get, UseGuards } from '@nestjs/common';
@Controller('admin')
@UseGuards(AuthGuard, RolesGuard) // AuthGuard와 RolesGuard를 함께 적용
export class AdminController {
@Get()
findAll() {
return 'This action returns all admin resources';
}
}
위처럼 Admin 권한을 부여받은 로그인한 유저만 해당 API에 접근할 수 있게 작성할 수 있습니다.
@UseGuards 데코레이터는 특정 라우트 핸들러나 컨트롤러에 가드를 적용하는 데 사용됩니다.
이 데코레이터는 내부적으로 NestJS의 DI 컨테이너를 사용하여 가드의 인스턴스를 생성하고, 라우트가 호출될 때 해당 인스턴스의 canActivate 메서드를 호출합니다.
동작방식
1. 가드 정의: 가드는 클래스 수준에서 정의되며, CanActivate 인터페이스를 구현합니다.
2. 가드 주입: 가드 클래스는 @Injectable() 데코레이터를 통해 DI 컨테이너에 주입될 수 있게 합니다. 이는 서비스, 컨트롤러, 모듈 등과 동일한 방식으로 작동합니다.
3. @UseGuards 데코레이터 적용: 특정 컨트롤러나 라우트 핸들러에 가드를 적용합니다.
4. DI 컨테이너 사용: 라우트가 호출될 때, NestJS는 DI 컨테이너를 사용하여 가드의 인스턴스를 생성하고, 해당 인스턴스의 canActivate 메서드를 호출하여 요청을 처리할 수 있는지 확인합니다.
사용자 정의 메타데이터 설정
사용자 정의 메타데이터(custom metadata)는 특정 핸들러나 클래스에 대해 추가 정보를 제공하기 위해 사용됩니다.
이러한 메타데이터는 NestJS의 반사(reflection) 기능을 통해 접근할 수 있으며, 이를 활용하여 다양한 동작을 정의하거나 제어할 수 있습니다.
NestJS에서는 @SetMetadata() 데코레이터를 사용하여 사용자 정의 메타데이터를 설정할 수 있습니다.
이 메타데이터는 특정 핸들러나 클래스에 부착되며, Reflector를 통해 나중에 읽을 수 있습니다.
1. 역할 정의
먼저, 역할을 정의하는 enum을 작성합니다.
export enum Role {
User = 'user',
Admin = 'admin',
}
2. 역할 데코레이터 작성
다음으로, 역할을 설정하는 데 사용할 커스텀 데코레이터를 작성합니다.
이 데코레이터는 @SetMetadata()를 사용하여 메타데이터를 설정합니다.
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: Role[]) => SetMetadata('roles', roles);
3. 역할 가드 작성
이제 역할 기반 접근 제어를 구현할 가드를 작성합니다.
이 가드는 실행 컨텍스트와 Reflector를 사용하여 메타데이터를 읽고 검증합니다.
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Role } from './role.enum';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<Role[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return roles.some((role) => user.roles?.includes(role));
}
}
4. 컨트롤러에 역할 데코레이터 적용
이제 특정 핸들러에 역할 데코레이터를 적용할 수 있습니다.
import { Controller, Get, Post, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
import { Role } from './role.enum';
@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {
@Get()
@Roles(Role.User)
findAll() {
return ['This action returns all cats'];
}
@Post()
@Roles(Role.Admin)
create() {
return 'This action adds a new cat';
}
}
참고
Guard
https://docs.nestjs.com/guards
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
사용자 정의 권한 부여
https://docs.nestjs.com/security/authorization
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
'JaveScript > NestJS' 카테고리의 다른 글
예외 필터 (0) | 2024.06.13 |
---|---|
Middleware (0) | 2024.06.11 |
@Module() (0) | 2024.06.10 |
Provider (0) | 2024.06.09 |
@Body() 데코레이터 (1) | 2024.06.08 |