Language/기타

JWT란?

건담아빠 2024. 12. 13. 15:12

오랜만에 SpringBoot에서 JWT를 다시 설정하면서 용어 등 원리등을 정리해두자. 대부분이 GPT내용이긴 하지만 정리하면서 머리속에 넣자!

 

JWT란?

JWT는 JSON Web Token의 약자로, JSON 형식의 데이터를 사용하여 양측 간에 정보를 안전하게 전달하기 위한 토큰

보통 인증 및 권한 부여와 같은 작업에 많이 사용

 

JWT구성

JWT는 .으로 구분된 3개의 파트로 구성된다.

header.payload.signature
ex) eyJhbGUzI1NiJ9.eyJzdWIiOiJfQ.nYAjp4ZHK8

 

1. header (헤더)

  • JWT의 타입과 서명 알고리즘 정보를 포함
  • 예시 (Base64로 인코딩되기 전)
{
  "alg": "HS256",  // HMAC SHA256 서명 알고리즘
  "typ": "JWT"     // Token의 유형
}

 

2. Payload (페이로드)

  • 토큰에 담길 실제 데이터 (클레임, claims)를 포함
  • 클레임은 두 가지 유형으로 나뉨
    • 등록된 클레임: 표준화된 필드 (예: iss, sub, exp 등)
    • 사용자 정의 클레임: 애플리케이션에 맞게 정의한 데이터
  • 예시 (Base64로 인코딩되기 전)
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

 

3. Signature (서명)

  • JWT의 무결성을 검증하기 위한 서명 부분
  • 서명 생성 방법:
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

 

JWT의 특징

1. Self-contained (자급자족형)

  • JWT는 필요한 정보를 자체적으로 포함하므로 별도의 상태 관리가 필요

 

2. Compact (간결성)

  • 텍스트 기반이기 때문에 HTTP 헤더, URL 등에서 쉽게 전달될 수 있음

 

3. 기밀성 (Confidentiality)

  • 토큰은 기본적으로 서명되지만 암호화는 아니다.
  • 중요한 정보는 암호화된 JWE(JSON Web Encryption) 사용을 권장

 

4. 플랫폼 독립성

  • JSON 형식을 사용하므로 언어나 플랫폼에 종속되지 않음

 

JWT의 사용 사례

1. 인증 (Authentication)

  • 사용자가 로그인을 완료하면 서버는 JWT를 발급하고, 이후 요청 시 클라이언트는 이 토큰을 전송한다.
  • 서버는 토큰을 검증하여 사용자를 인증한다.

 

2. 권한 부여 (Authorization)

  • JWT에 포함된 사용자 역할이나 권한 정보(예: admin: true)를 기반으로 권한을 관리한다.

 

3. 정보 교환 (Information Exchange)

  • JWT는 두 시스템 간에 신뢰할 수 있는 정보를 안전하게 교환할 수 있다.

 

JWT의 장점

  • 무상태성: 서버는 별도로 세션을 저장하지 않아도 된다.
  • 빠른 검증: 토큰의 서명만 검증하면 유효성을 확인할 수 있다.
  • 확장성: 다중 서비스 환경에서 인증 정보를 중앙화 없이 공유 가능하다.

 

JWT의 단점

  • 크기 증가: 토큰이 항상 JSON 데이터를 포함하므로 URL 또는 헤더 크기가 커질 수 있다.
  • 취소 불가능: 서버는 발급된 JWT를 별도의 조치를 취하지 않으면 무효화할 수 없다.
  • 보안 위험: 중요한 데이터를 암호화하지 않고 담으면 민감 정보가 노출될 수 있다. 토큰 유효기간(exp) 관리가 필수적이다.

 

JWT 사용 흐름

  1. 사용자가 로그인 요청.
  2. 서버가 JWT를 생성하여 클라이언트에 반환.
  3. 클라이언트는 이후 요청 시 JWT를 HTTP 헤더(Authorization: Bearer <token>)에 포함하여 전송.
  4. 서버는 JWT를 검증하여 요청을 처리.

 

예제

  • JWT 디코딩 전
eyJhbGUzI1NiJ9.eyJzdWIiOiJfQ.nYAjp4ZHK8
  • JWT 디코딩 후
Header:
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload:
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
Signature: (SHA256 signature)