[컴][웹] JWT, Json Web Token 이 무엇일까?

JWT 에 대해서 알아보자. / JWT 동작 원리




JWT, Json Web Token

Json Web Token  이다. 인증등을 위한 json 형식의 token 이라고 보면 된다. 대략적인 예제와 이야기는 아래글에서 파악하자.


훔쳐가되, 조작은 못한다.

필자가 파악한 이녀석의 의도는 OAuth 등의 목적과 비슷하다.
api 등을 사용하는데 필요한 key (token) 을 훔쳐가서 쓸 수는 있지만, 너희들이 이 key 를 만들어서 쓰거나, 훔친 key 를 조작할 수는 없을 것이다.
라는 전제를 깔고 있다. 그리고 이 전제는 기본적으로 web 상에서 훔침을 당하는 행위를 방지 할 수 없다는 뜻도 내포한다고 본다.


OAuth 1.0a 와 차이

ref. 2 에 따르면 이 JWT 도 OAuth 2.0 spec 안에 들어가는 듯 하다. 그러므로 아래 이야기는 OAuth 1.0 과의 차이로 생각하고 보도록 하자.

기존의 OAuth 와 비교해 본다면 결국 좀 더 자세한 정보를 전달할 수 있다는 점이 차이일 것이다. 그래서 OAuth 의 비해서 JWT 이 얻는 이득은 아래와 같다. (위 목록의 Using JSON Web Tokens as API Keys 를 참고하자.)
  • OAuth 는 인증이 됐다는 의미만을 가지고, 그 token 자체에 어떠한 의미를 전달할 수 없다. 이 때문에 단편적인 정보만을 전달한다. 하지만 JWT 를 이용해서는 json 형식의 token 을 전달하기 때문에 json 으로 의미있는 내용을 전달할 수 있다. 예를 들면 auth level 같은 것들 말이다.
  • 이로 인해 또 한가지 expire time 을 정해줄 수 있다. OAuth 는 이러한 것들이 불가능하다고 할 수는 없지만, 한 번 token 을 생성하고 일정시간 후에 expired 한다는 개념보다는 한 번 만들어 놓고 계속 사용하는 개념이 강하다.(개인적인 생각이다.)
  • 그리고 OAuth 는 만들어 놓은 token 을 DB 등에 저장해 놓고, 비교하는 형식이지만, 이녀석은 그렇지 않다고 한다. 로그인의 세션처럼 그때 그때 만들어 사용하는 개념인 듯 하다.


여기까지는 필자가 위의 글을 읽고 파악한 JWT 의 특징이라고 하겠다. 어디까지나 개인적인 생각이다.


JWT 의 동작 및 구현

여하튼 여기서 얘기하고자 하는 것은 이런 분석이 아니라, 실질적으로 JWT 가 어떻게 구현된 건지에 대해 정리하려 한다. 대부분의 내용은 아래 글의 내용이다.

JWT 만들기

JWT 는 아래와 같은 모양으로 되어 있다.
JWT Header Segment.JWT Payload Segment.JWT Crypto Segment
아래와 같은 모양으로 되는 것은 JWT Compact Serialization 을 사용한 결과다. 또다른 Serialization 이 있는데, 이녀석을 이용하면 좀 더 다른 모양이 된다. 여기를 참고하자.

위의 JWT 에 대해 좀 더 자세히 이야기 해 보자.
JWT Header Segment.JWT Payload Segment.JWT Crypto Segment
여기서 JWT Payload segment 에는 JWT Claims 가 들어간다. 각각의 segment 는 아래 처럼 생겼다. JWT Crypto 는 "JWT Header + '.' + JWT Claims" 를 input 으로 해서 encryption 한 값이 된다.


JWT Header
{"typ":"JWT",
 "alg":"HS256"}
의 UTF-8 를 Base64url 로 encoding 한 값
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9


JWT Claims
{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}
의 UTF-8 를 Base64url 로 encoding 한 값
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ


JWT Crypto
alg(JWT Header + '.' + JWT Claims)
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
이 값의 UTF-8 을 이용해서 JWT Header의 algo 에 쓰여진 알고리즘으로 encryption 한다. 그리고 이렇게 나온 값을 다시 Base64url 로 encoding 한다. 그래서 아래처럼 나왔다고 가정하자.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

그러면 최종적인 JWT 는 아래와 같은 모양이 된다.(JWT Compact Serializer 를 사용했을 때)
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk


Validation

먼저 JWT Header, JWT Claims 는 JSON 형식이 맞는지를 확인하고, JWT Crypto 는 JWT Header, JWT Claims 를 이용해서 다시 만들어 보는 것으로 validate 를 한다.

이렇게 3개가 전부 validated 되면, JWT 가 괜찮다고 여기는 것이다. 이 사이트에서 확인 해 볼 수 있다.


어디에 실어 나를까?

이부분은 마음대로 해도 되는 듯 하다. http header 에 넣어서 사용해도 되고, 단순히 GET, POST 의 parameter 로 넘겨도 되는 듯 하다. 관련해서 parameter 가 더 작은 byte 를 소모한다는 내용의 글이 있으니 참고하자.



해킹에 대한 대비

이런 모양의 token 이라 결국 중간에서 token 을 steal 당할 수는 있다. 하지만 expired 기간을 짧게 가져가서 steal 당한 이후의 피해를 줄이는 방법으로 가야 하는 듯 하다.
expiration 에 대한 예는 아래 글을 확인하자.


See Also


  1. Django REST framework JWT



Reference

  1. JSON Web Token (JWT) - Claims and Signing
  2. OAuth 2.0 - Open API 인증을 위한 만능 도구상자 - tebica story



댓글 없음:

댓글 쓰기