일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 감소하는 수
- SW Expert Academy
- QueryDSL 기초
- 16234번
- 2020 카카오 인턴십
- 12865번
- 프로그래머스
- 키패드 누르기
- 백준 알고리즘
- 파이썬
- HTML 기초
- 1789번
- SW ExpertAcademy
- 베스트엘범
- 17144번
- 12869번
- 수식 최대화
- 경주로 건설
- 거울 설치
- 9095번
- pkce
- 1038번
- 14499번
- 보석 쇼핑
- 19238번
- 스타트 택시
- 빛의 경로 사이클
- 15686번
- python
- 미세먼지 안녕!
- Today
- Total
보물창고 블로그
JWT 파해치기 본문
1. 왜 JWT가 필요한가?
웹 애플리케이션에서 사용자 인증을 구현할 때, 가장 흔히 쓰이는 방식은 세션 기반 인증입니다. 하지만 이 방식은 서버가 세션 상태를 유지해야 하므로, 서버가 여러 대로 확장되거나 마이크로서비스 환경에서는 관리가 어렵습니다.
이러한 한계를 해결하기 위해 등장한 방식이 토큰 기반 인증입니다. 그중에서도 가장 널리 사용되는 방식이 바로 JWT (JSON Web Token)입니다.
JWT는 인증 정보를 토큰 형태로 클라이언트에 저장하고, 요청마다 이 토큰을 함께 보내 인증을 수행합니다.
2. JWT란? 구조 설명
JWT는 .(닷)으로 구분된 3개의 Base64Url 인코딩 문자열로 구성됩니다:
header.payload.signature
각 부분의 역할은 다음과 같습니다
Header : 토큰의 유형(주로 JWT)과 사용된 서명 알고리즘(예: HMAC SHA256 또는 RSA)을 나타냅니다.
{
"alg": "HS256",
"typ": "JWT"
}
Payload : 토큰에 담길 데이터가 포함됩니다. 이 데이터는 클레임(claims)이라고 불리며, 주로 사용자의 정보나 권한 등의 데이터를 포함합니다. 페이로드의 데이터는 기본적으로 암호화되지 않아서 누구나 볼 수 있습니다. 따라서 민감한 정보는 포함하지 않아야 합니다.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature : 헤더와 페이로드를 조합하여 서명하는 부분입니다. 이를 통해 토큰이 위조되지 않았는지 검증할 수 있습니다. 서명은 비밀 키 또는 공개/개인 키 쌍을 사용해 생성됩니다.
서명 = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret_key)
3. JWT 사용 흐름
- 사용자가 로그인하면 서버는 사용자 정보를 바탕으로 JWT를 생성해 클라이언트에 전달합니다.
- 클라이언트는 JWT를 저장 (로컬스토리지, 쿠키 등)
- 이후 클라이언트는 요청 시 Authorization: Bearer <token> 헤더에 JWT를 포함합니다.
- 서버는 이 JWT의 서명을 검증하고, 유효하면 인증된 사용자로 간주합니다.
4. 서명 방식: HMAC vs RSA
🔐 HMAC (대칭 키 방식)
- 하나의 비밀 키로 서명과 검증 모두 수행
- 간단하고 빠름
- 단점: 키를 여러 서버 간에 안전하게 공유해야 함
🔑 RSA (비대칭 키 방식)
- 개인 키로 서명, 공개 키로 검증
- 공개 키를 여러 서버에 배포할 수 있어 분산 환경에 적합
- 다소 복잡하지만 보안성 높음
🔐 RSA의 두 가지 사용 방식
① 기밀성 (암호화) | 공개 키로 암호화 | 개인 키로 복호화 | 수신자의 공개 키로 암호화 → 수신자만(개인 키 보유자) 복호화 가능 |
② 무결성과 인증 (전자서명) | 개인 키로 서명 | 공개 키로 검증 | 발신자가 개인 키로 서명 → 누구나 공개 키로 검증 가능 |
🔒 기밀성을 위한 RSA:
- 공개 키로 암호화, 개인 키로 복호화
- 메시지를 비밀스럽게 전달할 때
✅ 서명/인증을 위한 RSA (JWT에서 사용하는 방식):
- 개인 키로 서명, 공개 키로 검증
- 메시지가 위조되지 않았음을 증명할 때 (신뢰성 보장)
5. JWT의 장단점
✅ 장점
- 상태를 저장하지 않기 때문에 확장성과 성능에 유리
- 다양한 플랫폼에서 사용 가능 (Node, Java, Python 등)
- RESTful API 인증에 적합
❌ 단점
- 토큰이 탈취되면 일정 시간 동안 악용 가능
- 중간에 토큰을 무효화하는 것이 어려움 (보통 블랙리스트 처리 필요)
- 토큰 크기가 커질 수 있음
6. 실전 예시 (Java)
String[] parts = jwt.split("\\.");
String payload = new String(Base64.getUrlDecoder().decode(parts[1]));
System.out.println("Decoded Payload: " + payload);
// HMAC 서명 검증 예시 (HS256)
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
String signature = Base64.getUrlEncoder().withoutPadding().encodeToString(
sha256_HMAC.doFinal((header + "." + payload).getBytes()));
7. 마무리: 언제, 어떻게 써야 할까?
JWT는 매우 강력한 인증 방식이지만, 사용하는 목적과 상황에 따라 주의가 필요합니다.
- 짧은 만료 시간, HTTPS 통신, 민감한 정보는 저장 금지 등의 보안 수칙을 꼭 지켜야 합니다.
- 또한 필요하다면 토큰 무효화를 위한 블랙리스트 시스템을 병행하는 것이 좋습니다.
✅ "JWT는 만능은 아니지만, 잘 사용하면 매우 유용한 인증 도구입니다."
📌 참고 링크
- 공식 스펙: https://datatracker.ietf.org/doc/html/rfc7519
- JWT 디코더: https://jwt.io
'웹 개발 > Computer Science Note' 카테고리의 다른 글
CORS(Cross-Origin Resource Sharing) 파헤치기 (1) | 2025.05.18 |
---|---|
Spring Interceptor 파헤치기 (0) | 2025.05.11 |
Spring filter 파헤치기 (0) | 2025.05.10 |
Oauth 파헤치기 (1) | 2025.05.02 |