토큰(token)은 본래 ‘징표’, ‘형식물’이라는 뜻에서 유래하여 상품권이나 서비스의 교환권을 뜻하는 영단어로, 화폐의 기능을 대신하는 유가증권의 일종이다. 실물로 주조될 경우 대개 화폐와 비슷한 모양으로 발급되며 재질은 동전부터 종이띠의 형태까지 다양하다.
대채적으로 주화 형태로 만든 대체 승차권. 종이로 만든 회수권과 함께 대중교통 운임 지불의 양대산맥이였으며 특히 버스토큰이 대표적이다.
토큰의 정의를 검색해보면 어떠한 교환권, 징표, 형식물이라는 의미에서 다른 사물과 구별하는 어떠한 표이다. 그렇가면 JWT 토큰은 무엇일까?
토큰은 비공개 시크릿 키 또는 공개/비공개 키를 사용하여 서명된다. 이를테면 서버는 "관리자로 로그인됨"이라는 클레임이 있는 토큰을 생성하여 이를 클라이언트에 제공할 수 있다. 그러면 클라이언트는 해당 토큰을 사용하여 관리자로 로그인됨을 증명한다.
위키백과에 나와있는 JWT와 토큰의 개념으로 유추해본다면 클라이언트(유저)의 권한을 식별하는 JSON 형태로 이루어진 징표라고 정의해볼 수 있다. 다시 말해 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다.
JWT는 어떤 구조로 이루어져 있길래 유저의 권한을 식별할 수 있는 징표일까? 자세히 알아보자.
JWT는 헤더, 페이로드, 서명으로 구성되며 각 요소는 .
으로 구분된다.
헤더와 페이로드는 JSON 기반의 key-value 형태로 구성이 되어있고 서명은 헤더, 페이로드, 암호화키 이 3가지와 헤더에서 정의한 해시 알고리즘을 기반으로 생성된다.
헤더의 “alg” Key는 algorithm의 약자로 value에는 서명 생성을 위한 해시 알고리즘의 종류가 담겨져있다.
일반적으로 SHA-2(HS256), SHA-256(RS256) 방식의 알고리즘이 주로 사용된다.
나중에 서명을 생성할 때 사용하는 암호화 알고리즘이다. ‘typ”는 “type”의 약자로 토큰의 타입을 의미한다. JWT는 “JWT”라는 문자열을 고정값으로 갖는다.
페이로드에는 실제 JWT 토큰을 통해 알 수 있는 데이터를 담는다.
이 정보는 클레임(Claim)이라고 부르며 key- value 한쌍으로 이루어 져있다. 그리고 페이로드에 여러개의 클레임을 담을 수 있고 클레임은 등록 클레임 (Registered claims)과 사용자 지정 클레임(Custom claims)으로 구분된다.
사용자 지정 클레임은 다시 공개 클레임(Public claims)과 비공개 클레임(Private Claims)로 구분된다.
등록 클레임(Registered claims)
Registered cliams은 필수는 아니지만 사용을 권장하는 미리 정의된 클레임의 집합이다.
이러한 클레임은 발급자, 주체, 대상 및 만료 시간과 같은 토큰 및 콘텐츠에 대한 표준 정보 집합을 제공한다.
다음은 JWT에서 일반적으로 사용되는 7개의 예약된 클레임이다.
자세한 내용은 IANA JSON 웹 토큰 클레임 레지스트리에서 확인할 수 있다.
사용자 지정 클레임(Custom claims)
사용자 지정 클레임은 제목 또는 토큰에 대한 사용자 지정 정보를 나타내기 위해 페이로드에 추가할 수 있는 클레임이다. 예를들어 “role”이라는 사용자 지정 클레임을 정의하고 해당 값을 “admin” 혹은 “user”로 정의하여 관리자인지 일반 유저인지 식별할 수 있다.
사용자 지정 클레임은 공개 클레임과 비공개 클레임으로 정의할 수 있다. 공개클래임은 IANA JSON 웹 토큰 클레임 레지스트리에 정의된 클레임인 반면 비공개 클레임은 자체 애플리케이션 내에서만 사용되는 클레임이다.
JWT는 일반적으로 암호화되지 않은 형태로 네트워크를 통해 전송되므로 민감한 정보에 사용자 지정 클레임을 사용하면 안된다.
서명은 Base64로 Encoding된 Header와 Payload를 "." (마침표)로 연결한 문자열과 사용자가 임의로 설정한 Secret Key로 암호화한 뒤 다시 Base64로 Encoding하여 생성한다. JWT를 수신한 App은 수신한 JWT의 Header, Payload 및 자신이 알고 있는 Secret Key를 이용하여 Signature를 생성한 다음, 수신한 JWT의 Signature와 비교한다. 만약 두 Signature가 동일하다면 해당 JWT는 유효하다는 의미한다.
JWT 서명은 JWT 페이로드의 무결성을 보장하고 JWT 발신자의 신뢰성을 확인하기 위해 생성된다. 서명은 비밀 키로 JWT 헤더와 페이로드에 서명하여 생성된다.
JWT 서명이 일반적으로 생성되는 방법은 다음과 같다.
RFC ft-ietf-oauth-json-web-token: JSON Web Token (JWT)