JWT (JSON Web Token)의 공식 홈페이지에서 소개글을 번역하자면, JWT는 개방형 표준(RFC 7519)으로 두 당사자간에 정보를 JSON 형태로 안전하게 전송하기 위한 방법이라고 소개한다.
일반적으로 클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한 인가(Authorization)를 위해 사용하는 토큰이다.
Stateless (무상태)
기존의 세션을 이용한 서버 기반 인증 방식의 경우 세션을 관리하기 위한 서버측 저장소에 대한 관리가 필요하지만, JWT는 서버에서 발급 후 검증만 하면 되기 때문에 서버측 저장소에 대한 관리가 필요 없다.
Scalability (확장성)
토큰 기반으로 하는 다른 인증 시스템에 접근할 수 있으므로 확장성이 좋다. 예를 들어, Google 로그인 등을 통한 어플리케이션 접근 등은 모두 토큰을 기반으로 인증하며, 선택적으로 이름이나 이메일 정보를 받을 수 있는 권한도 받을 수 있다.
Integrity (무결성)
JWT의 Secret key가 변경되면 Signature 영역이 변경된다. 이는 Token이 변조되었을 때 바로 알아차릴수 있음을 의미하므로 다시 말해, 콘텐츠가 변조되지 않았는지 확인할 수 있어 무결성을 보장한다.
JWT의 구조는 Header, Payload, Signature 문자열들이 각 점(.) 으로 구분되어있다.
JSON 객체를 문자열로 직렬화 하고, UTF-8과 Base64URLSafe로 인코딩하여 Header를 생성할 수 있다.
Header는 JWT를 어떻게 검증(Verify) 하는가에 대한 내용을 담고 있다.
alg는 서명 및 토큰 검증에 사용되는 알고리즘을 지정하고,
kid는 서명 시 사용하는 Public/Private Key를 식별하는 값이다.
Payload는 JWT의 내용이다. Payload에 있는 속성들을 클레임 셋(Claim Set)이라고 부르며, Claim Set은 토큰 생성자(클라이언트)의 정보, 생성 일시 등이나 클라이언트와 서버 간 주고 받기로 한 값들로 구성된다.
단, Payload는 암호화 되지 않으므로 암호화를 별도로 하거나 중요한 데이터를 담지 않아야 한다.
클레임 셋(Claim Set)
클레임 셋은 등록된 클레임(Registered Claim), 공개 클레임(Public Claim), 비공개 클레임(Private Claim)으로 구성되어 있다.
Signature는 Header와 Payload를 합친 문자열을 서명한 값이다. Signature는 Header의 alg에 정의된 알고리즘과 서버가 지정한 비밀 키를 이용해 생성하고, Base64 URL-Safe로 인코딩 한다.
Header, Payload, Signature를 합쳐 완성된 JWT는 Header의 alg, kid 속성과 공개 키를 이용해 검증할 수 있고, 검증에 성공하면 JWT의 모든 내용을 신뢰할 수 있으며, Payload 값으로 접근 제어 등의 처리를 할 수 있다.
리소스에 직접 접근할 수 있도록 해주는 정보만 가지고 있다.
Access Token이 탈취당하면 정보가 유출되므로 Refresh Token에 비해 짧은 만료기간을 가지고 있다.
새로운 Access Token을 발급받기 위한 정보를 가지고 있다.
Access Token에 비해 긴 만료기간을 가지고 있다.
Access Token이 만료되면 Refresh Token을 이용하여 서버에서 새로운 Access Token을 발급 받는다.