🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

JWT 테스트 전략 완벽 가이드 - 슬라이드 1/13
A

AI Generated

2025. 11. 1. · 55 Views

JWT 테스트 전략 완벽 가이드

JWT 인증 시스템의 테스트 전략을 단계별로 학습합니다. 토큰 생성부터 검증, 만료, 보안 테스트까지 실전 예제로 다룹니다.


카테고리:TypeScript
언어:TypeScript
메인 태그:#TypeScript
서브 태그:
#JWT#Testing#Authentication#Security

들어가며

이 글에서는 JWT 테스트 전략 완벽 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. JWT_토큰_생성_테스트
  2. 토큰_만료_시간_테스트
  3. 잘못된_시크릿_검증_테스트
  4. 리프레시_토큰_테스트
  5. 커스텀_클레임_검증_테스트
  6. 토큰_블랙리스트_테스트
  7. 비대칭_암호화_테스트_RS256
  8. 토큰_페이로드_크기_제한_테스트
  9. 토큰_재발급_플로우_테스트
  10. JWT_헤더_검증_테스트
  11. 동시_요청_토큰_검증_테스트
  12. 토큰_클레임_타입_검증_테스트

1. JWT 토큰 생성 테스트

개요

JWT 토큰이 올바른 페이로드와 시크릿으로 생성되는지 검증합니다. 생성된 토큰의 구조와 내용을 확인하는 기본 테스트입니다.

코드 예제

```typescript
import jwt from 'jsonwebtoken';

const payload = { userId: 123, role: 'admin' };
const secret = 'test-secret-key';
const token = jwt.sign(payload, secret, { expiresIn: '1h' });

const decoded = jwt.verify(token, secret) as any;
expect(decoded.userId).toBe(123);
expect(decoded.role).toBe('admin');

### 설명

sign() 메서드로 토큰을 생성하고, verify()로 디코딩하여 페이로드가 정확히 포함되었는지 검증합니다.

---

## 2. 토큰_만료_시간_테스트

### 개요

JWT 토큰의 만료 시간이 정확히 설정되고 만료된 토큰은 검증에 실패하는지 테스트합니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign({ userId: 1 }, secret, { expiresIn: '1s' });

await new Promise(resolve => setTimeout(resolve, 2000));

expect(() => {
  jwt.verify(token, secret);
}).toThrow('jwt expired');

### 설명

1초 만료 시간을 설정하고 2초 대기 후 검증하면 만료 에러가 발생합니다. 타임아웃 로직이 정확히 작동하는지 확인합니다.

---

## 3. 잘못된_시크릿_검증_테스트

### 개요

다른 시크릿 키로 서명된 토큰을 검증할 때 실패하는지 테스트합니다. 보안의 핵심 요소입니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign({ userId: 1 }, 'correct-secret', { expiresIn: '1h' });

expect(() => {
  jwt.verify(token, 'wrong-secret');
}).toThrow('invalid signature');

### 설명

올바르지 않은 시크릿으로 검증 시도 시 signature 에러가 발생하여 위변조된 토큰을 차단합니다.

---

## 4. 리프레시_토큰_테스트

### 개요

액세스 토큰과 리프레시 토큰을 분리하여 관리하는 전략을 테스트합니다. 보안성과 사용자 경험을 동시에 개선합니다.

### 코드 예제

```typescript
```typescript
const accessToken = jwt.sign({ userId: 1 }, secret, { expiresIn: '15m' });
const refreshToken = jwt.sign({ userId: 1 }, secret, { expiresIn: '7d' });

const access = jwt.verify(accessToken, secret) as any;
const refresh = jwt.verify(refreshToken, secret) as any;

expect(access.exp - access.iat).toBe(15 * 60);
expect(refresh.exp - refresh.iat).toBe(7 * 24 * 60 * 60);

### 설명

액세스 토큰은 15분, 리프레시 토큰은 7일로 설정하여 만료 시간 차이를 검증합니다.

---

## 5. 커스텀_클레임_검증_테스트

### 개요

JWT에 포함된 커스텀 클레임(권한, 역할 등)을 검증하여 인가 로직을 테스트합니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign(
  { userId: 1, role: 'admin', permissions: ['read', 'write'] },
  secret
);

const decoded = jwt.verify(token, secret) as any;
expect(decoded.permissions).toContain('write');
expect(decoded.role).toBe('admin');

### 설명

페이로드에 권한 정보를 포함시키고 디코딩 후 정확한 권한이 할당되었는지 확인합니다.

---

## 6. 토큰_블랙리스트_테스트

### 개요

로그아웃된 토큰을 블랙리스트에 등록하고, 해당 토큰 사용을 차단하는 로직을 테스트합니다.

### 코드 예제

```typescript
```typescript
const blacklist = new Set<string>();
const token = jwt.sign({ userId: 1 }, secret);

blacklist.add(token);

const isBlacklisted = blacklist.has(token);
expect(isBlacklisted).toBe(true);
expect(() => validateToken(token, blacklist)).toThrow('Token revoked');

### 설명

Set 자료구조로 블랙리스트를 관리하고, 검증 시 블랙리스트 포함 여부를 확인하여 접근을 차단합니다.

---

## 7. 비대칭_암호화_테스트_RS256

### 개요

RSA 키 쌍을 사용한 비대칭 암호화 JWT를 테스트합니다. 공개키로 검증하고 개인키로 서명하는 구조입니다.

### 코드 예제

```typescript
```typescript
import { generateKeyPairSync } from 'crypto';

const { privateKey, publicKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048
});

const token = jwt.sign({ userId: 1 }, privateKey, { algorithm: 'RS256' });
const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
expect(decoded).toHaveProperty('userId', 1);

### 설명

RSA 키 쌍을 생성하여 개인키로 서명하고 공개키로 검증합니다. 대칭키보다 안전한 방식입니다.

---

## 8. 토큰_페이로드_크기_제한_테스트

### 개요

JWT 페이로드가 너무 커지면 성능과 보안에 문제가 발생합니다. 적절한 크기 제한을 테스트합니다.

### 코드 예제

```typescript
```typescript
const largePayload = { data: 'x'.repeat(10000) };
const token = jwt.sign(largePayload, secret);

expect(token.length).toBeLessThan(15000);
expect(() => {
  if (token.length > 15000) throw new Error('Token too large');
}).not.toThrow();

### 설명

페이로드 크기를 의도적으로 늘려 생성된 토큰 길이를 검증합니다. 실전에서는 페이로드를 최소화해야 합니다.

---

## 9. 토큰_재발급_플로우_테스트

### 개요

만료된 액세스 토큰을 리프레시 토큰으로 재발급하는 전체 플로우를 통합 테스트합니다.

### 코드 예제

```typescript
```typescript
const access = jwt.sign({ userId: 1 }, secret, { expiresIn: '1s' });
const refresh = jwt.sign({ userId: 1 }, secret, { expiresIn: '1h' });

await new Promise(r => setTimeout(r, 2000));

const { userId } = jwt.verify(refresh, secret) as any;
const newAccess = jwt.sign({ userId }, secret, { expiresIn: '15m' });
expect(jwt.verify(newAccess, secret)).toHaveProperty('userId', 1);

### 설명

액세스 토큰 만료 후 리프레시 토큰으로 새 액세스 토큰을 발급하는 실전 시나리오를 검증합니다.

---

## 10. JWT_헤더_검증_테스트

### 개요

JWT 헤더에 포함된 알고리즘과 타입 정보를 검증하여 알고리즘 공격을 방지합니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign({ userId: 1 }, secret, { algorithm: 'HS256' });
const decoded = jwt.decode(token, { complete: true });

expect(decoded?.header.alg).toBe('HS256');
expect(decoded?.header.typ).toBe('JWT');
expect(['HS256', 'RS256']).toContain(decoded?.header.alg);

### 설명

complete 옵션으로 헤더까지 디코딩하여 허용된 알고리즘인지 검증합니다. 'none' 알고리즘 공격을 방어합니다.

---

## 11. 동시_요청_토큰_검증_테스트

### 개요

동일한 토큰으로 여러 동시 요청이 발생할 때 모두 정상 검증되는지 테스트합니다. 동시성 처리를 확인합니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign({ userId: 1 }, secret);

const promises = Array(100).fill(0).map(() =>
  Promise.resolve(jwt.verify(token, secret))
);

const results = await Promise.all(promises);
expect(results.every(r => (r as any).userId === 1)).toBe(true);

### 설명

100개의 동시 검증 요청을 Promise.all로 처리하여 모든 결과가 일관되게 성공하는지 확인합니다.

---

## 12. 토큰_클레임_타입_검증_테스트

### 개요

JWT 표준 클레임(iss, sub, aud 등)의 타입과 값을 검증하여 스펙 준수를 테스트합니다.

### 코드 예제

```typescript
```typescript
const token = jwt.sign(
  { sub: '1234567890', iss: 'myapp', aud: 'api' },
  secret
);

const decoded = jwt.verify(token, secret, {
  issuer: 'myapp',
  audience: 'api'
}) as any;

expect(decoded.sub).toBe('1234567890');
expect(decoded.iss).toBe('myapp');

### 설명

verify 옵션으로 issuer와 audience를 명시하여 토큰의 출처와 대상을 엄격하게 검증합니다. --- 이 카드 뉴스는 JWT 테스트의 핵심 전략을 실전 코드와 함께 제공합니다. 기본 생성/검증부터 보안, 만료, 블랙리스트, 비대칭 암호화, 동시성까지 고급 개발자가 알아야 할 모든 테스트 시나리오를 포함했습니다.

---

## 마치며

이번 글에서는 JWT 테스트 전략 완벽 가이드에 대해 알아보았습니다.
총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

### 관련 태그

#TypeScript #JWT #Testing #Authentication #Security
#TypeScript#JWT#Testing#Authentication#Security

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

UX와 협업 패턴 완벽 가이드

AI 에이전트와 사용자 간의 효과적인 협업을 위한 UX 패턴을 다룹니다. 프롬프트 핸드오프부터 인터럽트 처리까지, 현대적인 에이전트 시스템 설계의 핵심을 배웁니다.

Sandboxing & Execution Control 완벽 가이드

AI 에이전트가 코드를 실행할 때 반드시 필요한 보안 기술인 샌드박싱과 실행 제어에 대해 알아봅니다. 격리된 환경에서 안전하게 코드를 실행하고, 악성 동작을 탐지하는 방법을 단계별로 설명합니다.

Security & Safety Patterns 완벽 가이드

AI 에이전트와 클라우드 환경에서 필수적인 보안 패턴을 다룹니다. 격리된 실행 환경부터 민감 정보 보호까지, 초급 개발자가 알아야 할 보안의 기초를 실무 예제와 함께 배워봅니다.

AI 에이전트 신뢰성 완벽 가이드 - 가드레일과 평가 시스템

AI 에이전트가 예상치 못한 행동을 하지 않도록 안전장치를 설계하고, 품질을 체계적으로 평가하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 가드레일 패턴과 평가 프레임워크를 다룹니다.

Flutter Flame 게임 테스팅과 디버깅 완벽 가이드

Flutter와 Flame 엔진으로 개발한 게임의 품질을 보장하는 테스팅 기법과 디버깅 도구를 다룹니다. 단위 테스트부터 골든 테스트, 크래시 리포팅까지 실무에서 바로 적용할 수 있는 내용을 담았습니다.