NestJS Guard에 대한 설명과 예시 정리
Guard는 NestJS에서 요청이 처리되기 전에 실행되는 미들웨어와 유사한 역할을 하는 컴포넌트입니다. 주로 요청을 인증하거나 특정 조건을 확인하여 요청의 허용 여부를 결정하는 데 사용됩니다.
Guard는 다음과 같은 특징을 가집니다:
- 클래스 기반: Guard는 클래스이고,
@Injectable()
데코레이터로 정의됩니다. - CanActivate 메서드: 모든 Guard는
CanActivate
메서드를 구현해야 하며, 이 메서드에서 요청의 허용 여부를true
또는false
로 반환합니다. - 의존성 주입 가능: Guard 클래스는 의존성을 주입받아 사용할 수 있습니다.
- 컨트롤러 또는 라우트에 적용: Guard는 특정 컨트롤러나 라우트에 적용할 수 있습니다.
코드 예제를 통한 설명
1. BearerTokenGuard
BearerTokenGuard
는 기본적인 인증 Guard로, 요청 헤더에 포함된 Bearer 토큰을 추출하고 유효성을 검증합니다.
작동 방식:
authorization
헤더에서 토큰 값을 추출합니다.- 토큰을 검증(
authService.verifyToken
)하여 유효성을 확인합니다. - 검증 결과에서 사용자 정보를 조회(
usersService.getUserByEmail
)하고, 요청 객체(req)에 사용자와 토큰 정보를 추가합니다.
코드 핵심:
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const rawToken = req.headers['authorization'];
if (!rawToken) {
throw new UnauthorizedException('토큰이 없습니다!');
}
const token = this.authService.extractTokenFromHeader(rawToken, true);
const result = await this.authService.verifyToken(token);
const user = await this.usersService.getUserByEmail(result.email);
req.user = user;
req.token = token;
req.tokenType = result.type;
return true;
}
2. AccessTokenGuard
AccessTokenGuard
는BearerTokenGuard
를 상속받아 Access Token만 허용하도록 확장되었습니다.
작동 방식:
- 상속받은
canActivate
메서드를 호출하여 기본 Bearer 토큰 인증을 수행합니다. - 요청 객체에 추가된
tokenType
이access
인지 확인합니다. - Access Token이 아닌 경우 예외를 발생시킵니다.
코드 핵심:
if (req.tokenType !== 'access') {
throw new UnauthorizedException('Access Token이 아닙니다.');
}
3. RefreshTokenGuard
RefreshTokenGuard
는BearerTokenGuard
를 상속받아 Refresh Token만 허용하도록 확장되었습니다.
작동 방식:
- 상속받은
canActivate
메서드를 호출하여 기본 Bearer 토큰 인증을 수행합니다. - 요청 객체에 추가된
tokenType
이refresh
인지 확인합니다. - Refresh Token이 아닌 경우 예외를 발생시킵니다.
코드 핵심:
if (req.tokenType !== 'refresh') {
throw new UnauthorizedException('Refresh Token이 아닙니다.');
}
Guard 적용 예시
postPosts
메서드에서 AccessTokenGuard를 사용한 예시를 보면 Guard가 어떻게 사용되는지 알 수 있습니다.
코드:
@Post()
@UseGuards(AccessTokenGuard)
postPosts(
@User() user: UsersModel,
@Body('title') title: string,
@Body('content') content: string,
) {
return this.postsService.createPost(user.id, title, content);
}
동작 과정:
- 요청이
postPosts
메서드로 들어오면AccessTokenGuard
가 실행됩니다. AccessTokenGuard
는 Bearer 토큰을 검증하고, 토큰 유형이access
인지 확인합니다.- 검증을 통과한 경우, 요청은 컨트롤러의 핸들러로 전달됩니다.
@User()
데코레이터를 통해req.user
에 저장된 사용자 정보를 가져옵니다.- 사용자 정보와 제목, 내용을
postsService.createPost
에 전달합니다.
Guard의 계층 구조와 역할
1. BearerTokenGuard
:
- 토큰을 검증하고 사용자 정보를 요청 객체에 저장합니다.
- 토큰 유형(access, refresh)에 대한 구분은 하지 않습니다.
2. AccessTokenGuard
와 RefreshTokenGuard
:
BearerTokenGuard
를 확장하여 각각 Access Token과 Refresh Token만 허용하도록 세분화합니다.- 특정 토큰 유형만 허용하므로 보안성이 강화됩니다.
Guard의 활용 장점
- 코드 재사용성: 여러 컨트롤러와 라우트에서 동일한 인증 로직을 재사용할 수 있습니다.
- 모듈화: 인증과 관련된 로직을 Guard로 분리하여 코드의 가독성과 유지보수성을 높입니다.
- 유연성: Guard를 계층적으로 설계하여 다양한 인증 및 검증 로직을 구현할 수 있습니다.
이 코드에서 Guard는 토큰 기반 인증 시스템에서 핵심적인 역할을 하며, 역할에 따라 세분화된 Guard를 통해 보안성을 높이고 코드의 재사용성을 극대화하고 있습니다.
'NestJS' 카테고리의 다른 글
NestJS DTO,Validation (0) | 2024.11.18 |
---|---|
NestJS 데코레이터 (0) | 2024.11.16 |
NestJS 핫리로드 트러블슈팅 (1) | 2024.11.16 |
NestJS Pipe (0) | 2024.11.15 |
회원가입로직 (2) | 2024.11.14 |