JWT 란?
JSON 웹 토큰(JWT)은 두 주체 사이에 클레임 묶음을 실어 나르는 짧고 URL 에 안전한 형식이다. base64url 로 인코딩된 세 조각을 점으로 이어 붙인 것으로, 서명 알고리즘을 적은 헤더, 클레임이 든 페이로드, 앞의 둘에 대한 서명으로 이루어진다. 앞의 두 조각은 인코딩됐을 뿐 암호화된 것이 아니어서, 토큰을 가진 사람은 누구나 그 안을 읽을 수 있다.
이 디코더는 토큰을 갈라 헤더와 페이로드를 정리된 JSON 으로 보여주고, 표준 시각 클레임(exp·iat·nbf)을 읽히는 시각으로 바꾸며, 이미 만료됐거나 아직 유효하지 않은 토큰을 표시한다. 서명은 검증하지 않는다. 이 구분이 중요하다 — 디코딩은 토큰이 무엇을 주장하는지 알려줄 뿐, 그 주장이 진짜인지는 말해 주지 않는다.
The JWT Claims Set represents a JSON object whose members are the claims conveyed by the JWT.
기능
- 만료를 시각으로 읽는다
- exp·iat·nbf 를 날것의 유닉스 초가 아니라 ISO 시각으로 보여주고, 만료됐거나 아직 유효하지 않으면 그 자리에 표시한다.
- 밀리초 실수를 잡아낸다
- JWT 의 시각 클레임은 초 단위다. 밀리초로 발급된 토큰은 수만 년 뒤 날짜로 풀리는데, 디코더가 자릿수를 보고 알려 준다. 영문 모를 인증 버그가 한 줄 수정으로 바뀐다.
- alg: none 을 경고한다
- 헤더가 "none" 인 토큰은 서명이 아예 없다. 빨간색으로 짚어 준다 — 그런 토큰을 받아 주는 서버는 위조 토큰을 받아 주고 있는 것이다.
- 못 하는 일을 숨기지 않는다
- 서명은 보여주되 확인하지 않는다. 그 사실을 페이로드 아래가 아니라 위에 적는다. 클레임을 믿기 전에 읽히도록.
- 실제 토큰도 안전하게
- 디코딩은 브라우저에서 일어난다. 토큰이 서버로 전송되거나 기록되거나 저장되지 않으므로 운영 환경의 액세스 토큰도 남에게 넘기지 않고 들여다볼 수 있다.
사용법
- 1
토큰을 붙여넣는다
왼쪽에 JWT 를 붙여넣는다. 앞에 붙은 "Bearer " 는 알아서 떼어낸다.
- 2
클레임을 읽는다
클레임 목록이 필드마다 값을 보여주고, exp·iat·nbf 는 읽히는 시각으로 바꿔 준다.
- 3
만료를 확인한다
만료된 토큰은 exp 옆에 빨갛게 표시된다. 아직 유효하지 않은 토큰은 nbf 옆에 표시된다.
- 4
서명은 확인되지 않았음을 기억한다
페이로드는 토큰이 무엇을 주장하는지 파악하는 데 쓰고, 그 주장이 참이라는 증거로 쓰지 않는다.
자주 묻는 질문
서명을 검증해 주나?
일부러 하지 않는다. 검증하려면 발급자의 비밀키나 공개키가 있어야 하는데, 서명 비밀키를 웹 페이지에 붙여넣는 것은 그 페이지를 믿을 수 있더라도 나쁜 습관이다. 검증은 키가 기기 밖으로 나가지 않는 자기 코드나 CLI 에서 한다.
JWT 는 암호화되어 있나?
기본적으로는 아니다. 일반적인 서명 JWT(JWS)는 서명된 것이지 암호화된 것이 아니다 — 헤더와 페이로드는 base64url 로 인코딩됐을 뿐이라 토큰을 가진 사람은 누구나 읽는다. 비밀번호·개인정보·비밀값을 JWT 페이로드에 넣으면 안 된다. 암호화된 토큰은 JWE 라는 별도 형식이고 생김새가 다르다.
토큰이 언제 만료되는지 어떻게 보나?
exp 클레임에 1970-01-01 UTC 부터의 초 단위로 만료 시각이 들어 있다. 이 디코더가 그것을 읽히는 시각으로 바꾸고, 그 시점이 지났으면 만료됨으로 표시한다.
토큰의 날짜가 서기 5만 년으로 나온다
시각 클레임이 초가 아니라 밀리초로 발급된 것이다. JWT 의 시각 클레임은 초 단위로 정의되어 있어(RFC 7519 §2) 밀리초 값은 천 배 크다. 디코더가 이 경우를 표시해 준다.
토큰이 디코딩되지 않는다
복사가 잘렸거나(JWT 는 점으로 나뉜 세 조각이어야 한다), JWT 가 아닌 세션 쿠키이거나, 값과 함께 공백이 딸려 온 경우가 흔하다. 오류 메시지에 세 조각 중 어디서 실패했는지 나온다.
운영 토큰을 붙여넣어도 되나?
토큰은 사용자의 기기에서 자바스크립트로 풀리고 어디로도 전송되지 않는다 — 이 페이지에는 백엔드가 없다. 다만 토큰은 자격증명이다. 가능하면 만료된 토큰이나 테스트 토큰을 쓰고, 출처가 미덥지 않은 도구에 붙여넣은 값은 교체하는 편이 좋다.
여기서 막힌다면
이 도구가 따르는 규격
- RFC 7519 — JSON 웹 토큰(JWT) — exp·iat·nbf 를 NumericDate 로 정의한다 — 밀리초가 아니라 초다(§2).
- RFC 7515 — JSON 웹 서명(JWS) — 세 조각 직렬화와 "alg" 헤더를 정의한다. "none" 이 왜 위험한지도 여기 있다.
- OWASP — JSON Web Token 치트시트 — 풀린 페이로드가 왜 토큰이 진짜라는 증거가 될 수 없는지.