JWT 개념
JWT 란?

JWT 의 개념

참고한 자료는 아래와 같습니다. 아래 자료의 내용을 일부 의역 + 요약했습니다.


JWT 란?

JWT 는 RFC7519 로 등록된 하나의 기술 표준인데 사전적 정의는 "당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준(RFC7519)" 입니다.

주로 HMAC 알고리즘 또는 RSA 알고리즘을 통해 인코딩/디코딩을 합니다. JWT는 '서명된 토큰'에 중점을 둡니다. 당사자 간에 Secret 을 제공할 수도 있지만 '서명된 토큰'을 주고받는 것에 중점을 두고 있습니다.

서명된 토큰에는 이 토큰 내에 포함된 어떤 정보(=클레임)의 무결성을 확인할 수 있게 해줍니다.

개인적인 경험으로는 JWT 내에 여러가지 값을 넣을 수도 있지만 주로 변하지 않을 값들 (id, email) 등과 같은 값을 넣어두는게 좋고 자주 변하는 값 (profileImageId, phoneNumber 등) 과 같은 값들을 넣어두는 것은 비즈니스 요구사항 발생시 앱 재배포 이슈까지 따라올 수 있기에 좋지 않은 선택입니다.


JWT 의 구조

JWT 는 헤더, 페이로드, 서명(Signature) 로 구성됩니다.
예를 들면 . 으로 구분된 아래와 같은 형식으로 구성됩니다.

  • {header}.{Payload}.{Signature}
  • xxxxx.yyyyy.zzzzz

header (헤더) - "어떤 알고리즘을 사용해서 서명을 했는지"

header 는 아래와 같은 구조의 문자열로 구성되는데, 이 문자열을 Base64 URL 로 인코딩해서 JWT 의 첫번째 부분에 지정합니다.

{
    "alg": "HS256",
    "typ": "JWT"
}

payload (페이로드) - "JWT에 실어보낼 페이로드"

페이로드는 클레임들의 집합입니다.

e.g.

{
  "sub": "1234567890", // 등록된 클레임
  "name": "John Doe", // 개인클레임 
  "admin": true // 개인클레임
}

페이로드에는 클레임을 포함하고 있습니다.

클레임은 일종의 엔티티 및 부가정보에 대한 선언문이라고 생각하면 됩니다.

클레임의 유형은 3가지가 있습니다.

  • Registered Claim
    • 필수는 아닙니다. 하지만 권장됩니다.
    • Claim 들의 집합인데, 권장되는 Claim 들의 집합입니다. 필수는 아닙니다.
    • 안넣어도 되고, 엄청 중요한 것은 아닙니다.
    • e.g. iss(issuer), exp(expiration time), sub(subject), aud(audience), 그 외 기타 (opens in a new tab)
  • Public Claim
  • Private Claim
    • 개인이 필요할 때 만들어서 추가해서 넣을 수 있는 클레임입니다.
    • 사용자임을 식별할 수 있는 어떠한 primary key 같은 것들을 Primary Claim 에 넣는 경우가 많습니다.
    • 개인적으로 추가되는 정보임을 나타내는 정보
    • e.g. "user_id" : 1

핵심은 페이로드에 무엇을 넣는지입니다. 그 중 가장 중요한 것은 Private Claim (개인 클레임) 입니다. 예를 들면 이 개인 클레임(Private Claim)에는 user_id 나 primary_key 같은 식별 가능한 키를 암호화해서 넣는 편입니다.


Signature (서명)

header, payload 와 secret(개인키, 일반적으로 서버에서 따로 보안된 위치에 따로 보관)를 HMAC 으로 암호화하는 것을 의미합니다. HS256 이라는 것은 HMAC SHA 256 이라는 알고리즘을 의미합니다.

secret 이라는 것은 사용자가 지정한 임의의 문자열입니다.

예를 들면 'abcdefghijklmnopqrstuvwxyz1234567' 같은 문자열을 팀에서 키를 조합할때 사용할 비밀키로 지정했을 때 이 'abcdefghijklmnopqrstuvwxyz1234567 라는 문자열과 header, payload 값을 HMACSHA256 함수에 인자로 해서 생성하면 서명된 문자열이 도출됩니다.

이것을 서명이라고 이야기합니다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

최종 산출 결과

최종적으로 만들어진 JWT 는 아래와 같은 모습을 가지게 됩니다.

이미지 출처 : https://jwt.io/introduction (opens in a new tab)


만약 최종적으로 만들어진 JWT를 분해해서 확인해보고 싶다면 아래와 같이 jwt.io.Debugger 를 활용하시면 웹 GUI 로도 확인이 가능합니다.

이미지 출처 : https://jwt.io/introduction (opens in a new tab)