🤖

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

⚠️

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

이미지 로딩 중...

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

AI Generated

2025. 11. 1. · 26 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)

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

함께 보면 좋은 카드 뉴스