JWT

개요

JSON Web Token.
흔히 HTTP 통신 간 신원을 제공하기 위해 사용되는 토큰으로, RFC 7519에 정의됐다.
가장 흔하게 사용되는 영역이 OAuth, OIDC 인데, JWT라는 토큰 형식이 이들의 기반이 되어준다고 이해하면 좋다.
이름의 유래가 굉장히 단순한데, 그냥 웹 환경에서 JSON 형식으로 만들어진 토큰이라서 JWT이다.

https://jwt.io/
위 사이트가 jwt 토큰을 쉽게 분석해볼 수 있는 사이트로 매우매우 유명하다.

구조

image.png
JWT 토큰은 위와 같이 세 부분으로 나뉘며, 각 부분은 base64로 인코딩된다.[1]
일단 헤더와 페이로드가 있는데, 그 값들을 합쳐서 개인키로 암호화한 값을 서명 부분에 달아둔다.
이 토큰을 받은 대상은 공개키로 서명 부분은 복호화해보고 헤더와 내용이 위변조됐는지 확인할 수 있다.
즉, JWT는 어떠한 내용을 담고, 이 내용이 신뢰되는 주체로부터 서명 받은 것을 인증하는데 가장 큰 목적을 둔다.
헤더는 그냥 암호화 방식이랑 유형을 간단하게 나타내고 실제 내용은 페이로드에 전부 들어간다고 보면 된다.

Payload

페이로드 부분에는 임의의 내용을 때려박을 수 있는데, 이때 각 필드를 claim이라고 부른다.
이 토큰이 어떤 내용을 담고 있다, 주장(claim)을 하는 것이기 때문에 이리 부른다고 한다(gpt 피셜).
그래도 조금 RFC로 규정된 형태의 필드들이 있긴 하다.

뭐.. 이렇긴 한데 사실 이거 다 쓰는 토큰을 거의 본 적이 없다.
그리고 이거 말고도 임의의 클레임을 넣어도 상관이 없어서 그걸 활용하는 케이스가 대부분이기도 하다.
표준이지만 너무 나이브한 표준인

JWE? JWS? JWKS?

JWT와 관련해서 나오는 몇 가지 개념들이 추가적으로 있다.
사실 JWT는 이런 식으로 만든 토큰 인터페이스라고 보면 된다.
이걸 실제 토큰으로 구현할 때는 두 가지 방식이 존재한다.

그러니 흔히 JWT라고 하면 JWS 형식이라고 보면 되겠다.

그렇다면 JWKS는 무엇인가?

https://<server_domain>/.well-known/jwks.json

JSON Web Key Set은 서명된 값을 확인하는 데 사용되는 키 집합을 말한다.
받은 JWT토큰을 검증하기 위해서는 암호화할 때 사용된 몇 가지 값을 알아야 한다.
그래서 보통 암호화를 한 주체는 해당 값들을 알 수 있도록 위의 경로를 노출한다.

{
  "keys": [
    {
      "kty": "EC",
      "crv": "P-256",
      "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
      "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
      "use": "enc",
      "kid": "1"
    },
    {
      "kty": "RSA",
      "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
      "e": "AQAB",
      "alg": "RS256",
      "kid": "2011-04-29"
    }
  ]
}

대체로 위 경로에는 이런 식으로 값이 담겨 있으며, 이를 기반으로 JWT를 검증하려는 측은 위변조 유무를 파악할 수 있다.[3]

디코딩

jwtd () {
  local input="${1:-}"
  if [ -z "$input" ]; then
    if [ ! -t 0 ]; then
      input=$(cat /dev/stdin)
    else
      echo >&2 '✗ Need an argument or have a piped input!'
      return 1
    fi
  fi
  echo "$input" \
    | jq -Rrce 'split(".")[1] | . + "=" * (. | 4 - length % 4)' \
    | openssl base64 -d -A \
    | jq .
}

간단하게 사용할 수 있는 쉘 스크립트를 만들어준 분이 있다.[4]
이걸 rc 파일에 넣건, 그냥 source를 하건 해서 파이프라인으로 전달하거나 jwt를 뒤에 박으면 된다.

아니면 위에 본 사이트를 이용해도 좋다.

관련 문서

이름 noteType created
OAuth knowledge 2025-05-09
5W - 이스티오 JWT 인증 published 2025-05-11

참고


  1. https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리 ↩︎

  2. https://auth-wiki.logto.io/ko/jwe ↩︎

  3. https://blog.advenoh.pe.kr/jwks-json-web-key-set이란/ ↩︎

  4. https://gist.github.com/angelo-v/e0208a18d455e2e6ea3c40ad637aac53?permalink_comment_id=5119116#gistcomment-5119116 ↩︎