학습 목표
JWT(JSON Web Token) 의 header·payload·signature 구조를 설명할 수 있다.
서명·검증으로 무결성을 보장하는 방식을 설명할 수 있다.
세션 쿠키와 JWT 무상태 인증의 차이를 비교할 수 있다.
토큰 저장 위치(메모리, localStorage, HttpOnly cookie) 트레이드오프를 설명할 수 있다.
문제 상황
- 마이크로서비스 10개인데 세션 스티키가 필수라고 한다
- 중앙 세션 저장소 없이 검증만 하고 싶다
- JWT를
localStorage에 넣었다가 XSS로 전부 털림- "JWT가 안전한 로그인"이 아니다
- payload를 Base64 디코딩해
role: admin을 직접 수정했다- 서명 검증 없이 믿으면 인증 우회
- 로그아웃해도 토큰이 만료 전까지 통한다
- 무상태 토큰의 철회 문제
인증 기초에서 세션·쿠키·해싱을 봤다. 이번 편은 자가 포함(self-contained) 토큰인 JWT다.
1. JWT란
JWT — 클레임(claims)을 JSON으로 담고, 서명으로 변조를 막는 토큰 형식 (RFC 7519).
- 주로 인증·인가에 쓰이지만, JWT 자체가 암호화는 아님 (기본은 JWS)
- Opaque token과 대비: JWT는 payload를 디코딩 가능 (비밀 넣지 말 것)
2. 구조
header.payload.signature — 점(.)으로 이은 세 부분, Base64URL 인코딩.

Header
{"alg": "HS256", "typ": "JWT"}
- alg: HMAC·RS256·ES256 등 — 검증 알고리즘 고정 (algorithm confusion 방지)
Payload (claims)
{
"sub": "user-42",
"role": "member",
"iat": 1719000000,
"exp": 1719003600
}
| claim | 의미 |
|---|---|
sub |
subject — 사용자 ID |
iss |
issuer |
aud |
audience |
exp |
만료 시각 (필수 권장) |
iat |
발급 시각 |
Signature
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
- 서버는 비밀키(대칭) 또는 공개키(비대칭)로 검증
- payload 변경 시 서명이 맞지 않음
3. 인증 흐름

- 클라이언트가 credential로 로그인
- 인증 서버가 JWT 발급
- 이후 요청
Authorization: Bearer <token> - 각 API가 서명·exp·aud 검증 — DB 세션 조회 불필요 (순수 stateless일 때)
| 세션 쿠키 | JWT (stateless) | |
|---|---|---|
| 상태 | 서버 저장소 | 토큰 자체에 claims |
| 확장 | 세션 공유·스티키 이슈 | 서비스마다 검증만 |
| 로그아웃 | 세션 삭제로 즉시 | 블랙리스트·짧은 exp 필요 |
| 크기 | 쿠키에 session id | claims 많으면 헤더 비대 |
4. 저장 위치 트레이드오프

| 위치 | XSS | CSRF | 비고 |
|---|---|---|---|
| 메모리 (JS 변수) | 탈취 가능 | 상대적 안전 | 새로고침 시 사라짐 |
| localStorage | 읽기 쉬움 | CSRF 덜함 | OWASP 비권장 |
| HttpOnly Secure cookie | JS 접근 불가 | SameSite 필요 | SPA+API에 흔한 절충 |
| BFF | 프론트에 토큰 안 둠 | BFF가 쿠키 관리 | 구조 복잡 |
- 어디에 두든 XSS를 막는 것이 선행 — JWT는 저장술이 아니다
5. 보안 체크리스트
| 항목 | 내용 |
|---|---|
exp·iat |
짧은 access token, refresh 분리 |
| 알고리즘 | allowlist (RS256만), none 금지 |
| 비밀 | HS256 secret 충분한 엔트로피, 키 로테이션 |
| 민감 정보 | payload에 PII·권한 과다 금지 |
| HTTPS | 전송 중 탈취 방지 |
| 철회 | refresh rotation, denylist, 짧은 TTL |
GET /api/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
- 인가는 JWT claims만 믿지 말고 리소스 소유·정책 재검증 (8편 RBAC)
6. 정리
- JWT = header + payload + 서명, payload는 인코딩일 뿐 암호화 아님
- 무상태 검증으로 MSA 확장에 유리, 로그아웃·철회는 별도 설계
- 저장 위치는 XSS·CSRF 트레이드오프 — HttpOnly cookie + SameSite가 흔한 선택
- OAuth·OIDC는 JWT를 어떻게 발급·위임하는지 다룬다 (다음 편들)
다음에 다룰 것
- OAuth 2.0
- grant type, authorization code + PKCE
해당 내용은 RFC 7519 (JSON Web Token) 및 OWASP JWT Cheat Sheet 의 내용을 기반으로 합니다.