jwtVerification
이 페이지에서 찾을 수 있는 것
| 심볼 | 분류 | 설명 |
|---|---|---|
jwtVerification | Middleware Factory | JWT Bearer 토큰 검증 미들웨어 |
개요
jwtVerification은 Express 미들웨어 팩토리로, 라우트 데코레이터의 auth 옵션에 따라 JWT 토큰 검증을 수행합니다. RouterController가 등록된 모든 라우트에 내부적으로 적용하므로, 일반적인 사용에서는 직접 호출할 필요가 없습니다.
import { jwtVerification } from '@asapjs/router';시그니처
const jwtVerification: (auth?: boolean) =>
(req: Request, res: Response, next: NextFunction) => void| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
auth | boolean | false | true이면 유효한 Bearer 토큰이 필요합니다. false이면 토큰이 있을 경우 수락하지만 필수는 아닙니다. |
동작 방식
미들웨어는 모든 요청에서 다음 로직을 실행합니다:
Authorization헤더를 읽습니다.- 헤더가 없는 경우:
auth === true→HttpException(403, 'NO Token Provided')를 throw합니다.auth === false→next()를 호출합니다.req.user는 설정되지 않습니다.
- 헤더가 있는 경우,
Bearer <token>형식에서 토큰을 추출하고config.auth.jwt_access_token_secret으로 검증합니다. - 검증 성공 → 디코딩된 페이로드를
req.user에 저장하고next()를 호출합니다. - 검증 실패,
auth === true→ 에러 유형에 따라 응답을 전송합니다. - 검증 실패,
auth === false→req.user를 설정하지 않고next()를 호출합니다.
에러 응답 형식
| 시나리오 | HTTP 상태 | 응답 경로 | 바디 |
|---|---|---|---|
토큰 없음, auth: true | 403 | throw HttpException → errorToResponse() | { status: 403, errorCode: 'LEGACY_HTTP_EXCEPTION', message: 'NO Token Provided' } |
유효하지 않은 서명, auth: true | 403 | res.json() 직접 응답 | { error: true, message: 'invaild signature...' } |
만료/유효하지 않은 토큰, auth: true | 401 | res.json() 직접 응답 | { error: true, message: 'Unauthorized access. Please Refresh Token' } |
실패, auth: false | — | 요청 계속 진행 | req.user는 undefined |
참고: 토큰 없음 케이스는
throw로 에러 파이프라인을 거쳐{ status, errorCode, message }형식이지만, JWT 검증 실패 케이스는res.json()직접 응답으로{ error, message }형식입니다. 클라이언트 에러 처리 시 두 가지 형식을 모두 고려해야 합니다.
IOptions의 auth 옵션과 연동
데코레이터의 auth 필드가 jwtVerification의 동작을 제어합니다:
import { Get, Post, ExecuteArgs } from '@asapjs/router';
// 공개 라우트 — 토큰 불필요
@Get('/posts', {
title: 'List posts',
auth: false, // 기본값; 생략 가능
})
async getPosts({ paging }: ExecuteArgs) { ... }
// 보호된 라우트 — 유효한 Bearer 토큰 필요
@Post('/posts', {
title: 'Create post',
auth: true,
body: CreatePostDto,
})
async createPost({ body, user }: ExecuteArgs) { ... }auth를 생략하면 기본값은 false입니다.
필수 설정
jwtVerification은 전역 설정 객체에서 시크릿을 읽습니다:
{
auth: {
jwt_access_token_secret: 'your-secret-key'
}
}설정은 런타임에 @asapjs/common의 getConfig()를 통해 접근합니다. 키가 없으면 첫 번째 인증 요청 시점에 JWT 검증이 오류를 던집니다.
JWT 토큰 형식
클라이언트는 Bearer 방식을 사용하여 Authorization 헤더에 토큰을 전달합니다:
Authorization: Bearer <jwt-token>미들웨어는 공백을 기준으로 분리하여 두 번째 세그먼트를 토큰 문자열로 사용합니다.
전체 컨트롤러 예제
공개 라우트(auth: false)와 보호된 라우트(auth: true)를 함께 사용하는 컨트롤러 예제입니다:
import { RouterController, Get, Post, ExecuteArgs } from '@asapjs/router';
import { HttpException } from '@asapjs/router';
import UserApplication from '../application/UserApplication';
import CreateUserDto from '../dto/CreateUserDto';
import LoginRequestDto from '../dto/LoginRequestDto';
import LoginResponseDto from '../dto/LoginResponseDto';
import UserInfoDto from '../dto/UserInfoDto';
export default class UserController extends RouterController {
public tag = 'User';
public basePath = '/users';
private userService: UserApplication;
constructor() {
super();
this.registerRoutes();
this.userService = new UserApplication();
}
// 공개 — 토큰 불필요
@Post('/register', {
title: 'Register',
description: 'Creates a new user account.',
body: CreateUserDto,
response: UserInfoDto,
})
async register({ body }: ExecuteArgs) {
return await this.userService.register(body as CreateUserDto);
}
// 공개 — 토큰 불필요
@Post('/login', {
title: 'Login',
description: 'Authenticates with email and password, returns a JWT.',
body: LoginRequestDto,
response: LoginResponseDto,
})
async login({ body }: ExecuteArgs) {
return await this.userService.login(body as LoginRequestDto);
}
// 보호된 라우트 — 유효한 Bearer 토큰 필요
@Get('/me', {
title: 'Get current user',
description: 'Returns the profile of the authenticated user.',
auth: true,
response: UserInfoDto,
})
async getMe({ user }: ExecuteArgs) {
if (!user?.id) {
throw new HttpException(401, 'Token payload missing user id');
}
return await this.userService.getUserInfo(user);
}
}관련 항목
- HTTP Method Decorators —
IOptions.auth필드 - ExecuteArgs —
user필드와 JWT 페이로드 - HttpException — JWT 에러에서 사용하는 예외 클래스
Last updated on