[Auth] JWT: 구조, 서명, 만료, refresh token
JWT, JSON Web Token, JWS, JWE, JWA, Bearer token, Refresh token, Access token, RS256, HS256
정의
JWT (JSON Web Token) (RFC 7519) 은 base64url 인코딩된 JSON + 서명 형태의 self-contained token. 서버가 세션 저장 없이 클레임 검증 가능.
구조: 3 부분
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsIm5hbWUiOiJrb2EiLCJleHAiOjE3MjAxMjM0NTZ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
↑ header ↑ payload ↑ signature
| 부분 | 형식 |
|---|---|
| Header | { "alg": "HS256", "typ": "JWT" } |
| Payload | { "sub": "42", "name": "koa", "exp": 1720123456 } |
| Signature | HMAC-SHA256(base64(header) + ”.” + base64(payload), secret) |
표준 클레임
| 클레임 | 의미 |
|---|---|
iss | issuer |
sub | subject (user ID) |
aud | audience |
exp | 만료 시각 (Unix epoch) |
nbf | not before |
iat | issued at |
jti | JWT ID (unique, replay 방지) |
서명 알고리즘
| Alg | 종류 | 비고 |
|---|---|---|
HS256/384/512 | HMAC (대칭) | 양측이 같은 secret. 내부 |
RS256/384/512 | RSA (비대칭) | private 으로 sign, public 으로 verify |
ES256/384/512 | ECDSA | 짧고 빠름 |
EdDSA | Ed25519 | 가장 빠름, 안전 |
none | 서명 없음 | 사용 금지 (취약점 다수) |
WARNING
alg: none 을 받는 라이브러리는 치명적 취약점. 항상 허용 alg 화이트리스트.
흐름
sequenceDiagram
autonumber
participant C as Client
participant Auth as Auth Server
participant API as API Server
C->>Auth: POST /login (id, password)
Auth->>Auth: 검증 + JWT 생성
Auth-->>C: { access_token, refresh_token }
C->>API: GET /me<br/>Authorization: Bearer <jwt>
API->>API: JWT 검증 (서명 + exp)
API-->>C: 200 OK
Note over C: 만료 임박
C->>Auth: POST /refresh (refresh_token)
Auth-->>C: 새 access_token
Access Token vs Refresh Token
| 항목 | Access Token | Refresh Token |
|---|---|---|
| 수명 | 짧음 (5분 ~ 1시간) | 길음 (7일 ~ 30일) |
| 저장 | 메모리 (브라우저 SPA) | HttpOnly cookie 또는 안전한 저장 |
| 매 요청 전송 | 예 | 갱신 시만 |
| 탈취 영향 | 짧은 시간 피해 | 큰 피해, 반드시 HttpOnly |
| Revoke | 만료까지 어려움 | DB 에 저장 + revoke 가능 |
IMPORTANT
Access token 을 localStorage 에 저장 하면 XSS 시 즉시 탈취. 메모리 + 새로고침 시 refresh 패턴이 정통.
Stateless vs Stateful
| Session (stateful) | JWT (stateless) | |
|---|---|---|
| 서버 저장소 | 필수 | 불필요 |
| Revoke | 즉시 | 만료까지 어려움 |
| 스케일 | sticky session 필요 | 수평 확장 자유 |
| 페이로드 | session ID 만 (작음) | 전체 클레임 (큼) |
| 갱신 | 서버 갱신 | 새 JWT 발급 |
CAUTION
“JWT 가 항상 더 좋다” 는 미신. 작은 monolith 에서는 session 이 더 단순 + 즉시 revoke 가능. JWT 는 분산 + 마이크로서비스 + 모바일 SDK 에서 진가.
Revoke 전략 (Stateless 의 단점 보완)
flowchart TD
Q{revoke 필요}
Q --> A[짧은 exp + refresh<br/>대부분의 경우]
Q --> B["Blacklist (Redis)<br/>jti 등록"]
Q --> C[Versioning<br/>user.token_version<br/>JWT 안에 version]
A --> Best[추천]
B --> Heavy[캐시 부담]
C --> Sync[DB 한 번 조회 필요]
XSS / CSRF 와의 관계
flowchart TD
Store{저장 위치}
Store --> A[localStorage] -->|XSS 시 탈취| Bad1[X]
Store --> B[메모리 + HttpOnly cookie refresh] -->|XSS 영향 적음| Good[O]
Store --> C[HttpOnly cookie + SameSite=Strict] -->|CSRF 안전 + XSS 안전| Best[권장]
IMPORTANT
Cookie 기반 이면 CSRF 방어 필요 (SameSite=Strict 또는 CSRF token). Bearer header 면 XSS 방어 가 중요.
흔한 함정
WARNING
alg: none허용 라이브러리 = 옛 라이브러리 일부. 즉시 업데이트.- HS256 vs RS256 혼동 = 공개키를 secret 으로 오해해 서명 받으면 모든 토큰 위조 가능 (CVE 다수).
- 만료 너무 김 = 탈취 시 피해 큼. 15분 ~ 1시간 권장.
- secret 이 짧음 =
secret같이 무차별 공격 가능한 키. 32+ 바이트 랜덤. - 민감 정보 페이로드 = JWT 는 암호화 아님 (base64 인코딩). password / 카드 번호 절대 금지.
JWE (암호화 변형)
JWT 가 서명만 이면 내용 노출. JWE 는 암호화 까지. 그러나 느리고 복잡. 대부분의 경우 민감 정보를 페이로드에 안 넣고 JWS (서명만) 만으로 충분.
관련 위키
이 글의 용어 (5개)
- [Auth] CSRF: 위조 요청 공격과 방어auth-security
- 정의 CSRF (Cross-Site Request Forgery) 는 사용자가 로그인된 상태 에서 공격자가 만든 페이지 가 피해자 브라우저로 위조 요청 을 보내는 공격. 쿠키 기…
- [Auth] OAuth 2.0 / 2.1: Authorization Code + PKCEauth-security
- 정의 OAuth 2.0 (RFC 6749, 2012) 은 제3자 앱이 사용자 동의로 자원에 접근 하게 하는 권한 위임 프레임워크. 인증 (authentication) 이 아니라 …
- [Auth] OpenID Connect (OIDC): OAuth 위의 인증 레이어auth-security
- 정의 OpenID Connect (OIDC) 는 OAuth 2.0 위에 얹은 인증 (authentication) 표준. OAuth 가 권한 위임 (authorization), O…
- [Auth] Session Cookie: HttpOnly, SameSite, Secure flagauth-security
- 정의 Session Cookie 는 서버가 발급한 임의 ID 를 쿠키에 보관. 매 요청 자동 첨부. 서버 측 세션 store (Redis, DB) 와 짝. [!IMPORTANT]…
- [Network] CORS: Same-Origin Policy, preflight, credentialsnetwork
- 정의 CORS (Cross-Origin Resource Sharing) 는 Same-Origin Policy (SOP) 의 완화 메커니즘. 브라우저가 origin 이 다른 리소스…
이 개념을 다룬 위키 페이지 (9)
- wiki[API Design] OpenAPI / Swagger: 스펙, 코드 생성, contract testing
- wiki[Auth] CSRF: 위조 요청 공격과 방어
- wiki[Auth] OAuth 2.0 / 2.1: Authorization Code + PKCE
- wiki[Auth] OpenID Connect (OIDC): OAuth 위의 인증 레이어
- wiki[Auth] SAML 2.0: XML 기반 기업 SSO
- wiki[Auth] Session Cookie: HttpOnly, SameSite, Secure flag
- wiki[Pattern] API Gateway: BFF, 라우팅, auth, rate limit
- wiki[DRF] Authentication: Session, Token, JWT, OAuth2
- wiki[Network] CORS: Same-Origin Policy, preflight, credentials
💬 댓글