목차 열기
인증 아키텍처
RSA 비대칭키 방식을 사용합니다. Auth-Guard가 개인키로 서명하고,API Gateway가 공개키로 검증합니다. Gateway만 JWT를 파싱하고, 하위 서비스는 X-User-Id 헤더만 읽습니다.
토큰 설계
| 토큰 | TTL | 저장 위치 | 용도 |
|---|---|---|---|
| Access Token | 15분 | 클라이언트 메모리 | API 인증 |
| Refresh Token | 4시간 (부하테스트용) / 설정 가능 | HttpOnly Cookie + Redis | 토큰 재발급 (RTR) |
| Admission Token | 15분 | HttpOnly Cookie | 대기열 통과 → Seat 진입권 |
| Seat Hold | 5분 | PostgreSQL (seat_holds) | 좌석 점유 → 주문 생성 권한 |
JWT 토큰 구조
Access Token Claims:
├─ sub: userId (subject)
├─ aud: JWT_ACCESS_TOKEN_AUDIENCE
├─ iss: JWT_ISSUER
├─ iat: 발급 시각
├─ exp: 만료 시각 (기본 15분)
├─ jti: 고유 토큰 ID (블랙리스트 키)
├─ tokenType: "ACCESS"
├─ auth: 권한 (ROLE_USER 등)
└─ sid: 세션 ID (RTR 시 유지)
Admission Token Claims (Queue → Seat 진입권):
├─ sub: userId
├─ matchId: 대상 경기 ID
├─ type: "ADMISSION"
├─ iss: "queue-service"
├─ exp: 15분 TTL
└─ jti: 고유 ID핵심 설계 포인트
RTR (Refresh Token Rotation)
토큰을 재발급할 때 기존 Refresh Token을 즉시 폐기하고 새 토큰을 발급합니다. 토큰이 탈취되더라도 재사용이 불가능하며, sid(세션 ID)는 유지되어 세션 추적이 가능합니다.
1. Client → POST /auth/token/refresh (쿠키에 Refresh Token)
2. Auth-Guard: Redis에서 기존 RT 검증 (jti 일치 확인)
3. 기존 RT 삭제 (Redis DEL)
4. 새 Access Token + 새 Refresh Token 발급 (sid 유지)
5. 새 RT를 Redis에 저장 (IP, UA 포함)
6. 만약 삭제된 RT로 재요청 → 401 (탈취 의심)블랙리스트 기반 로그아웃
로그아웃 시 Access Token의 JTI를 Redis 블랙리스트(token_blacklist:{jti})에 등록하고, 남은 TTL 동안 API Gateway에서 해당 토큰을 차단합니다 (Reactive Redis로 sub-ms 응답).
서비스 간 2단계 신뢰
서비스 간 신뢰는 Admission Token(대기열 → 좌석)과Seat Hold(좌석 → 주문) 2단계로 분리하여, 대기열 우회와 중복 주문을 원천 차단합니다.
Internal API Key (타이밍-세이프 비교)
/internal/**, /loadtest/** 엔드포인트는 X-Internal-Api-Key 헤더로 보호됩니다.MessageDigest.isEqual()을 사용하여 타이밍 공격을 방어합니다.
유저 차단 Kafka 연쇄 처리
AI 방어 서버
│ POST /internal/users/{userId}/block
│ Header: X-Internal-Api-Key: {secret}
▼
Auth-Guard
├─ 1. User.status = BLOCKED (PostgreSQL)
├─ 2. 차단 유저 로그인 시도 → 403 USER_ALREADY_BLOCKED
├─ 3. TransactionSynchronization.afterCommit()
└─ 4. Kafka publish → topic: user-blocked
▼
Order-Core (KafkaListener)
└─ 해당 userId의 활성 주문 → status = UNDER_REVIEW쿠키 보안 설정
Refresh Token과 Admission Token 모두 HttpOnly + Secure + SameSite=None로 설정되어 XSS 토큰 탈취와 CSRF 공격을 방어합니다.