JWT는 토큰 기반 인증 방식에서 주로 사용되는 토큰입니다. 주로 로그인 된 특정 사용자를 인증하기 위해서 사용됩니다. REST API 서버의 확장성을 높이는 데 JWT 인증 방식이 한 몫을 하고 있습니다. 이번 글에서는 JWT 구조에 대해 알아보겠습니다.

JWT란?

JWT는 Json Web Token의 약자입니다.
당사자들이 서로 Json 데이터를 안전하게 주고 받기 위해 고안된 표준입니다.

JWT 구조

JWT가 어떻게 생겼는지 봅시다.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJncmVlbm5ldXJvbkBlbWFpbC5jb20iLCJyb2xlIjoiUk9MRV9VU0VSIiwiaWF0IjoxNjc0ODg3NzM4LCJleHAiOjE2NzQ5NzQxMzh9.4koOlEtPTTObnMPk5xF3l2zuXRNnlkqYNg1eni8yit0

JWT 구조를 자세히 보면 “.” 을 구분자로 세 개의 파트로 나뉘어져 있는 것을 알 수 있습니다. 각 파트는 아래와 같이 각각 다른 이름과 역할을 가집니다.

Header.Payload.Signature

JWT의 각 파트는 base64Url 인코딩 되어 있습니다.
아래의 웹 페이지에서 누구나 토큰을 쉽게 디코딩 해볼 수 있습니다.

https://jwt.io/#debugger-io

헤더 (Header)

토큰의 타입과 사이닝 알고리즘에 대한 정보가 담겨있는 파트입니다.

Headerbase64Url 디코딩 결과
eyJhbGciOiJIUzI1NiJ9{"alg":"HS256"}
header를 base64Url 디코딩
  • typ : 토큰의 타입
  • alg : 서명 알고리즘 (the signing algorithm being used)

페이로드 (Payload)

어떤 상태 값이나 추가적인 정보가 담겨 있는 파트입니다. 권장하는 내용으로 미리 정의되어 있는 key-value를 담거나(https://www.rfc-editor.org/rfc/rfc7519#section-4.1), 개발자가 임의로 key-value를 정의하여 담을 수 있습니다. header, payload에 담긴 key-value들을 클레임(claim) 이라고 합니다.

Payloadbase64Url 디코딩 결과
eyJzdWIiOiJncmVlbm5ldXJvbkBlbWFpbC5jb20iLCJyb2xlIjoiUk9MRV9VU0VSIiwiaWF0IjoxNjc0ODg3NzM4LCJleHAiOjE2NzQ5NzQxMzh9{"sub":"greenneuron@email.com","role":"ROLE_USER","iat":1674887738,"exp":1674974138}
payload를 base64Url 디코딩
  • sub : 토큰 발행 시 지정된 JWT의 주체 (Principal)
  • iat : 토큰 발행 일시
  • exp : 토큰 만료 일시
  • role : 개발자가 임의로 추가한 claim

시그니처 (Signature)

Header에 명시된 서명 알고리즘으로 아래의 표와 같이 서명했을 때 생성된 Signature가 담겨있는 파트입니다. 서명에는 인코딩된 헤더, 인코딩된 페이로드와 Secret(토큰 발행 시 사용한 비밀키)가 필요합니다. 서명 시 생성된 문자열이 Signature와 동일한지 확인함으로써, 토큰 발행자는 전달 받은 토큰이 자신이 발행한 토큰이 맞는지, 변조되지 않은 유효한 토큰인지 검증할 수 있습니다.

Signature서명 방법 (Secret : greenneuron)
4koOlEtPTTObnMPk5xF3l2zuXRNnlkqYNg1eni8yit0HMACSHA256(
  base64UrlEncode(header) +"."+ base64UrlEncode(payload),
  "s6v8y/B?E(H+MbQeThWmZq4t7w!z$C&F"
)
Signature 생성 방법

참고 자료

스스로 경험하며 얻은 깨달음을 공유하기 좋아하며, 세상이 필요로 하는 코드를 작성하기 위해 노력하는 개발자입니다.

“JWT 구조 이해하기”의 2개의 댓글

  • 좋은 내용 감사합니다.
    Header, Payload에서 사용하는 Base64 인코딩은, 일반적인 Base64가 아니라, URL에서 사용할 수 있는 문자들만 사용하는 Base64URL 인코딩 방식인 것 같은데, Signature도 마찬가지로 URL에서 사용 가능한 문자만 포함되는 건가요?

    • 안녕하세요! 좋은 질문 감사합니다. RFC7519의 내용을 자세히 보니 다음과 같은 문장이 있었습니다.

      “A JWT is represented as a sequence of URL-safe parts separated by period (‘.’) characters. Each part contains a base64url-encoded value.”

      위 내용으로 보아 Signature 파트도 base64url 인코딩이 적용되어야 한다고 생각됩니다. 질문 주신 내용을 반영해서 글을 조금 수정하였습니다. 감사합니다👍

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다