JWT의 이해

in #kr7 years ago

1. JWT의 이해


근래에 들어서 Claim 기반의 토큰 방식인 JWT (JSON Web Token)가 많이 사용되고 있다.

여기서 Claim은 사용자에 대한 프로퍼티나 속성을 말한다. 토큰 자체가 정보를 가지는 방식인데, JWT는 이 Claim을 JSON을 이용해서 정의한다.

다음은 Claim을 JSON으로 서술한 예이다.



JSON은 '\n' 등 줄바꿈 문자가 있기 때문에 REST API 호출 시 HTTP 헤더 등에 넣기가 매우 불편하다. 그래서 JWT에서는 이 Claim JSON 문자열을 Base64 인코딩을 통해 하나의 문자열로 반환한다.

만약에 누군가 토큰을 변조해서 사용한다면 어떻게 할 것인가?

메시지가 변조되지 않았음을 증명하는 것이 무결성이라고 하는데, 무결성을 보장하는 방법 중 많이 사용되는 것이 서명(Signature)이나 HMAC를 사용하는 방식이다.

즉, 원본 메시지에서 해시 값을 추출하고, 이를 비밀 키를 이용해서 복호화 시켜 토큰의 뒤에 붙이는 방식이 HMAC 방식이다. 누군가 이 메시지를 변조했다면 변조된 메시지에서 생성한 해시 값과 토큰 뒤에 붙어 있는 HMAC 값이 다르므로 변조되었음을 알 수 있다.



A. 서명 생성 방식

무결성을 보장할 수 있는 알고리즘에는 HMAC SHA256 외에도 384, 512 그리고 공인인증서를 이용한 RS256 등 다양한 서명 방식을 지원한다. JWT 토큰의 맨 앞부분에는 서명에 어떤 알고리즘을 사용했는지를 JSON 형태로 정의한 후 Base64 방식으로 인코딩한 문자열을 붙인다.





서명 방식, JSON 기반의 Claim, 그리고 서명(Signature)까지 포함된 전체적인 JWT 토큰의 구조를 보면 다음과 같다.





EX )



2. 문제점


A. 길이

Claim에 넣는 데이터가 많아질수록 JWT 토큰의 길이가 길어진다. API 호출에 사용할 시에 호출마다 헤더에 붙어서 가야 하기 때문에 길이가 길다는 것은 그만큼 네트워크 대역폭 낭비가 심하다는 의미이다.

B. 한번 발급된 토큰은 값을 수정하거나 폐기가 불가

JWT는 토큰 내에 모든 정보를 다 가지고 있기 때문에 한번 발급된 토큰에 대한 변경은 서버에서는 더는 불가능하다. 토큰을 잘못 발행해서 삭제하고 싶더라도 서명만 맞으면 맞는 토큰으로 인식하기 때문에 한번 발급된 토큰의 정보를 바꾸는 것은 불가능하다. 그래서 만료 시간을 꼭 명시적으로 두도록 하고 Refresh Token 등을 이용해서 중간마다 토큰을 재발행하도록 해야한다.

C. 암호화

JWT는 기본적으로 Claim에 대한 정보를 암호화하지 않는다. 단순 Base64인코딩만 되기 때문에 중간에 패킷이 가로채지거나 기타 방법으로 토큰을 취득하게 되면 토큰 내부 정보를 통해서 사용자 정보가 누출될 가능성이 있다. 특히 자바스크립트 기반의 웹 클라이언트는 브라우저 상의 디버거 등을 통해 토큰이 노출될 수 있다. 이를 보완하는 방법으로는 JWE (JSON Web Encryption)가 있다.






참조 저서 : 조병욱(조대협), 대용량 아키텍처와 성능 튜닝, 프리렉 출판, 179쪽