콘텐츠로 건너뛰기

JWT 디코더

JWT(JSON Web Token)를 브라우저에서 디코딩하여 헤더, 페이로드, 서명을 시각화합니다.iat / exp / nbf 는 사람이 읽을 수 있는 날짜로 자동 변환됩니다.

완전 무료 가입 불필요 브라우저 완결 5 개 언어 다크 모드

JWT 구조에 대해

JWT는 header.payload.signature 세 부분을 점(.)으로 연결한 문자열입니다. 헤더와 페이로드는 Base64URL로 인코딩된 JSON이고, 서명은 헤더에 지정된 알고리즘(HS256 / RS256 등)으로 생성됩니다.

주요 클레임: iss(발급자), sub(주체), aud(수신자), exp(만료), nbf(유효 시작), iat(발급 시각), jti(JWT ID)

문제가 있거나 표시가 이상하면 다음으로 알려주세요: 문의 양식 으로 알려주세요.

📖 자주 걸리는 지점

JWT 의 헤더 · 페이로드 · 서명을 분해해 표시하고 expiat 같은 시각 클레임을 일시로 변환합니다. 처리는 브라우저 안에서 끝나며 서명의 검증은 하지 않습니다(키가 필요하므로). 여기서 짚어야 할 것은 디코딩할 수 있다는 것은 내용을 누구나 읽을 수 있다는 것이라는 점입니다 — JWT 의 페이로드는 암호화되어 있지 않고 단지 Base64URL 로 부호화되어 있을 뿐입니다.

사례 무슨 일이 일어나는가 어떻게 하면 되는가
페이로드에 기밀을 넣어 버린다 Base64URL 은 부호화이지 암호화가 아닙니다 — 이 페이지가 그러하듯 키를 갖지 않은 누구나 내용을 읽을 수 있습니다. 그런데도 서명되어 있으니 안전하다는 오해는 뿌리 깊어 페이로드에 개인정보 · 내부의 권한 구조 · 사내 ID, 때로는 메일 주소와 생년월일을 한꺼번에 넣어 버리는 설계가 보입니다. JWT 는 브라우저의 localStorage 나 쿠키에 저장되고 로그에도 남고 URL 에 실리는 경우도 있습니다내용은 공개 정보로 다뤄진다고 생각하는 것이 정확합니다. 페이로드에는 식별자만 넣고 내용은 서버에서 조회하세요 — 사용자 ID 와 역할 이름 정도로 그치고 성명 · 메일 주소 · 주소는 넣지 않습니다. 암호화가 필요하다면 JWE(JSON Web Encryption)라는 별도의 사양이 있습니다그 전에 애초에 JWT 에 넣을 필요가 있는지를 다시 물으세요 — 많은 경우 필요한 것은 누구인가뿐이고 무엇인가는 서버가 알고 있으면 충분합니다. 판단의 기준은 단순해서 그 값이 액세스 로그에 평문으로 나와도 괜찮은가 입니다 — 괜찮다면 넣어도 되고 곤란하다면 넣어서는 안 됩니다.
디코딩했을 뿐인데 내용을 믿어 버린다 서명을 검증하지 않으면 JWT 는 사용자가 자유롭게 고쳐 쓸 수 있는 문자열에 지나지 않습니다. 디코딩해 role: "admin" 을 읽고 그대로 권한 판정에 쓰는 코드는 공격자가 스스로 그 값을 쓴 토큰을 그대로 받아들입니다. 역사적으로 유명한 실패가 두 가지 있으며 하나는 alg: "none" 공격 — 헤더의 알고리즘을 none 으로 고쳐 쓰고 서명을 비우면 그것을 순순히 받아들이는 구현이 있었기 때문입니다. 또 하나는 HS256 과 RS256 의 혼동으로 공개 키를 HMAC 의 공유 키로 쓰게 함으로써 공개 정보만으로 유효한 서명을 만들 수 있게 됩니다. 검증은 반드시 라이브러리의 검증 함수로 하고 허용할 알고리즘을 명시적으로 고정하세요jwt.verify(token, key, { algorithms: ["RS256"] }) 처럼 씁니다. 이 인수를 생략하면 헤더의 alg 를 믿는 구현이 있습니다 — 공격자가 고쳐 쓸 수 있는 값을 검증 방식의 결정에 써서는 안 됩니다. 디코딩만 하는 함수(jwt.decode 같은 이름의 것)를 인가의 판단에 쓰지 마세요 — 이름이 비슷해 혼동되지만 이것은 검증을 하지 않습니다. 용도는 디버그 표시뿐입니다. 구현을 쓰기 전에 그 라이브러리의 검증하는 함수와 디코딩만 하는 함수를 반드시 확인하세요.
로그아웃했는데 토큰이 쓸 수 있다 JWT 는 스테이트리스인 것이 설계상의 이점이자 동시에 최대의 제약입니다. 서버는 토큰을 저장하고 있지 않으므로 발행한 토큰을 개별적으로 무효화할 수단이 없습니다 — 로그아웃이란 실제로는 클라이언트 쪽에서 토큰을 버리는 것에 지나지 않으며 그 토큰을 복사해 갖고 있던 자는 유효 기간까지 계속 쓸 수 있습니다. 같은 이유로 권한을 박탈해도 이미 발행된 토큰에는 옛 권한이 쓰인 채입니다. 퇴직자의 접근을 막았을 텐데 한 시간 쓸 수 있었다는 것이 이것입니다. 유효 기간을 짧게 하고 리프레시 토큰과 조합하세요 — 액세스 토큰은 15 분 정도로 하고 갱신에는 서버 쪽에서 관리하는 리프레시 토큰을 씁니다. 이 구성이라면 리프레시 토큰을 무효화함으로써 최대 15 분이면 권한이 끊깁니다. 즉시 실효가 요건이라면 블록리스트(실효시킨 토큰의 ID 를 저장하고 검증 시에 대조)가 필요합니다다만 이는 스테이트를 갖는다는 뜻이므로 JWT 를 쓰는 이점의 일부를 내려놓게 됩니다. 판단은 여기가 분기점으로 — 즉시 실효가 정말로 필요하다면 순순히 세션 ID 와 서버사이드 세션을 쓰는 편이 단순하고 확실합니다. JWT 가 맞는 것은 복수의 서비스를 넘나드는 인증이나 검증만을 분산시키고 싶은 경우입니다.

시각 클레임은 초입니다. exp · iat · nbf 는 모두 Unix 초이며 밀리초를 넣으면 유효 기간이 5 만 년 뒤가 되어 실질적으로 무기한인 토큰이 만들어집니다 — JavaScript 의 Date.now() 가 밀리초를 반환하므로 Date.now() + 3600000 처럼 써서 그대로 exp 에 넣는 실수는 대단히 자주 일어납니다(올바르게는 Math.floor(Date.now() / 1000) + 3600). 디코딩 결과의 일시가 먼 미래가 되어 있다면 이 실수를 의심하세요 — 이 페이지가 시각을 일시로 변환해 표시하는 것은 바로 그것을 눈으로 확인하기 위해서입니다. 한 가지 더, 서버 간 시계의 어긋남에 대비해 nbfexp 의 검증에는 수십 초의 허용(leeway)을 두세요 — 주요 라이브러리에는 그 옵션이 있습니다. 마지막으로 운용상의 주의로 유효 기간 내의 프로덕션 토큰을 외부의 온라인 JWT 디코더에 붙이지 마세요그것은 인증 정보 그 자체이며 붙인 곳의 서버 로그에 남으면 그대로 남이 사칭할 수 있습니다. 이 페이지는 브라우저 안에서 끝나지만 그 보장은 개발자 도구의 Network 탭에서 확인하는 습관을 가지세요.

📖 사용법

  1. 1
    JWT 복사
    API 응답이나 Authorization 헤더에서 JWT 문자열을 가져옵니다.
  2. 2
    입력란에 붙여넣기
    JWT를 상단 텍스트 영역에 붙여넣으면 자동으로 디코딩됩니다.
  3. 3
    헤더 · 페이로드 확인
    알고리즘(alg), 발급자(iss), 만료(exp) 등의 클레임을 시각적으로 확인합니다.

❓ 자주 묻는 질문

JWT란?
JWT(JSON Web Token)는 Base64URL 인코딩된 header/payload/signature를 점으로 연결한 인증 토큰입니다.
서명 검증도 가능한가요?
이 도구는 디코딩 전용입니다. 서명 검증은 시크릿이나 공개 키가 필요합니다.
입력한 JWT가 서버로 전송되나요?
아닙니다. 모든 디코딩은 브라우저의 JavaScript에서 완결되며 네트워크 통신이 발생하지 않습니다.
exp가 만료된 경우는?
만료된 JWT는 무효입니다. 리프레시 토큰으로 새 JWT를 받거나 재로그인하세요.
🐛 이 도구에서 문제가 발생했나요?

무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.

※ 재현을 위해 브라우저 정보 (UA / 화면 / 언어 / URL) 가 자동 전송됩니다