웹 개발

JWT - Json Web Token을 간단하게 정리해봅시다.

리차드 전 2021. 2. 1. 18:49

웹 기반에서 주로 쓰이는 JWT에 대해서 실용적으로 사용되는 방식을 아주 쉬운 방식으로 설명을 해보겠습니다. 

아래는 어디서든 찾아볼 수 있는 JWT의 구조 및 구현 방법입니다.

JWT 기본 구조 

기본적으로 스트링입니다. 웹 기반으로 통신할 때는 다 스트링 타입이죠. (바이트 스트리밍 방식으로도 요즘 많이 추가되는 추세이긴 합니다.) JWT는 세 부분으로 나눠져 있으며, 구분은. 을 이용합니다. 즉 아래와 같이 구성되어 있죠.

 

[header].[payload].[signature]

 

Json타입으로 정보를 저장하고 base64로 인코딩한 다음에 .으로 스트링 연결하면 완성이라는 뜻이죠. 

 

Header

header에는 주로 두 개의 값을 정의합니다.

  • alg : "HS256" , 사용할 해쉬 알고리즘을 정의
  • typ: "JWT", JWT형식이라는 것을 알림. 사실상 거의 고정적인 값. 

Payload

payload는 실제로 서버가 클라이언트로 알려주려고 하는 값이 저장되는 곳입니다. payload라는 영어 단어 때문에 한참 고민을 했었는데, 그냥 서버가 알려주려고 하는 값이 들어간다고 보면 될 것 같습니다. 주로 사용되는 값이 몇 개 정해져 있고, 추가로 임의로 사용해도 됩니다. 이 안에서 정의된 값들을 주로 claim이라고 부르는데요. 이는 registered, public, private의 3가지 타입으로 나뉩니다.  

 

Registered claim종류

  • iss : 발행인 정보
  • sub : 제목(subject) 
  • aud : Audience, 즉, 대상  
  • exp : 만료 날짜
  • nbf : (not before) 지정된 시점 이전에는 받아들이면 안 된다.
  • iat : (issued at) 발행한 시각.
  • jti  :  jwt의 고유 식별자.

미리 정의된 필드들이라고 이해하시면 쉬울 것 같습니다.  저 항목들에게는 항상 저 값이 저장된다고 보시면 됩니다. 반대로 JWT를 발행하는 입장에서는 저 필드에는 항상 저 값에 맞는 값을 저장해서 발행해야 합니다. 

 

Public Claim 

발행자가 임의로 만들어내서 쓸 수 있는 항목들을 말합니다. 단 Registered claim과 같은 내용을 쓰지 않도록 주의해야 합니다. 같은 내용을 쓰지 않기 위해서는 www.iana.org/assignments/jwt/jwt.xhtml 사이트를 참조하거나, 중복되지 않는 내용이 포함될 수 있는 URI 등을 이용해야 합니다.

 

Private Claim

발행자와 사용자가 서로 동의하게 정의해서 사용하는 항목들입니다. 이 내용들은 Registered나 Public에 포함되지 않는 항목들이어야 합니다. 

 

** 여러 가지 claim에 대해 정의하고 있지만, 실무에서 빠르고 간단하게 사용할 때에는 Registered Claim항목들 + 스스로 발행할 때 사용할 Private Claim위주로 정의해서 사용하면 됩니다. **


 

Signature

이 값은 payload에 저장된 값이 위변조 되었는지 확인할 때 사용하는 부분입니다. 이는 이미 전통적인 방식으로 전달되는 값과 자기 자신만이 알 수 있는 (알아야만 하는) secret값을 이용하여 단방향 해쉬 알고리즘으로 변환된 값을 이용하는 것과 같습니다. 이때 사용하는 해쉬 알고리즘은 header에서 정의한 방법을 따라야 합니다. header와 payload의 base64 값을 secrect값과 함께 해쉬값을 만들어내는 부분입니다. 

 

 

JWT 이용 예제 

 

JWT는 발급한 내용이 다른 구성요소들(클라이언트나 다른 서버)을 거쳐서 전달될 때 위변조 되지 않았음을 보증하는 방법을 제공합니다. 

 

가상의 앱 C는 A회사의 회원으로 가입되어 있는 자신의 인증 정보를 가지고 B회사의 서비스를 이용한다고 가정해봅시다. 

 

1. 앱 C는 A회사의 가입되어 있는 자신의 정보 (Id, e-mail)등을 B사에서 이용할 수 있게 JWT형식으로 달라고 요청합니다. 

2. A사는 B사와 미리 계약된 secrect키를 가지고 앱 C에게 Id, e-mail 등을 jwt에 넣고 지정된 해쉬 알고리즘으로 인코딩을 합니다. 

3. 앱 C는 A사로부터 받은 JWT를 B사에 전달해서 자신이 A사의 Id, e-mail을 갖고 있는 사람이라는 걸 알려줍니다.

4. B사는 전달받는 JWT와 A사와 이미 계약되고 공유되고 있는 secrect키를 가지고 signature를 만들어 본 후, 앱 C가 전달한 signature와 같은지 검사합니다. 

 

이런 시나리오로 앱 C는 별도의 회원가입 없이 A사의 인증 정보로 B사의 서비스를 이용하는 방식으로 제공받을 수 있습니다.