먼저 위의 개념을 간단하게 이해하는 것이 JWT를 이해하는데 훨씬 수월하다. HTTP 프로토콜의 경우, Stateless 프로토콜이다. 즉, Request하고 Response하면 끝나는 것이다. 상태가 없다는 의미다. 그러나 웹 서비스의 경우, Stateless하게 운영하게 되면 문제점은 지속적인 Credential 교환과 상태(로그인 정보/장바구니 등의 비즈니스 정보) 유지를 위한 빈번한 I/O 발생이다. 이런 문제점 때문에 쿠키/세션을 적용하며, 웹서비스 중에 쿠키/세션을 쓰지 않는 웹서비스는 거의 없을 것이다.
정리하면, Stateless와 Stateful의 큰차이점은 싸이클의 차이이다.
앞으로 설명할 JWT는 Stateless한 서비스에서 식별/인증/인가를 하기 위한 모델이며, Stateless 입장에서 생각하는게 이해하기 쉽다.
JWT 무엇인가
먼저 토큰은 토큰 기반 웹서비스 또는 REST API 웹서버에서 많이 사용된다. 해당 토큰 사용방식에 대해 규격화/구조화(즉, 표준)한 것 중 하나를 JWT(JSON Web Token)라고 생각하면 되겠다.
왜/언제 사용하는지에 대한 예는 아래와 같다.
보통의 웹 서비스(stateful)는 쿠키/세션을 활용하여 로그인 서비스 즉, 사용자 식별/인증/인가가 이루어진다. 그러나 REST API 웹서버의 경우 쿠키/세션을 활용하지 않는다. 즉, Stateless한 서버이다. 그러면 리소스(URI)에 접근할 때 식별/인증/인가는 어떻게 진행되는가? 이 때 사용되는 것이 토큰이며 앞으로 설명할 JWT가 될 것이다(토큰은 목적이며 JWT 수단이다. 즉, 다른 기술을(JWT 말고) 적용할 수 있다.).
목적
JWT의 목적은 서버 리소스에 접근하는 주체에 대해 식별/인증/인가를 진행하는 것이다.
JWT 사이클
1. 사용자는 ID/PW를 서버에 전송한다.
2. 서버는 ID/PW 인증을 실시한다. 성공할 경우, JWT 토큰을 발급한다.
3. 사용자는 JWT 토큰을 사용하여(헤더에 적재) 리소스에 접근한다.
4. 서버는 사용자의 JWT 토큰 무결성/유효성 검증을 실시한 후, 리소스를 반환한다.
JWT(JWS) 구조
위의 JWT 라이프 사이클에서 반환한 JWT 토큰의 구조는 아래와 같다(JWT는 인터페이스이며 구현체는 JWS와 JWE가 있다. 보편적으로 JWT를 얘기하면 JWS를 칭하는것과 같다. 앞으로 JWT라고 언급하면 JWS를 언급한다고 생각하면 되겠다.).
크게 헤더/페이로드/시그니처 3개의 부분으로 나누어져 있다. 구성은 아래와 같다.
-헤더: 토큰의 무결성 검증을 위한 값들을 지정
-페이로드: 토큰의 유효성 검사 및 비즈니스 로직에서 활용할 때 사용하는 정보
-시그니처: 토큰의 무결성 검증
JWT는 JSON으로 구성되어 있으며 구성요소는 아래와 같다. 위의 3가지 요소의 구분자는 “.” 온점이다. JSON으로 구성되어 있는 메시지를 Base64로 인코딩한다(정확히 얘기하면 Base64URL 인코딩을 한다. Base64와 Base64URL은 약간 다르다.).
전체적인 헤더 페이로드 구성은 토큰을 발급하는 서버가 항목을 지정한다. 예를 들어, 자주 사용되는 헤더는 아래와 같다.
- alg: Signature 생성 알고리즘
-typ: 토큰 타입
위의 2가지를 포함하여 더 많은 헤더를 적재할 수 있다. JOSE Header list의 링크는 아래와 같다.