JWT 디코더
header·payload·만료 확인. 검증 X · 전송 X.

JWT 토큰 만료와 payload 확인하는 법 (2026)

401이 떴는데 토큰 만료인지 권한 문제인지 헷갈릴 때. JWT의 payload와 exp를 안전하게 읽는 법을 정리합니다.

초록빛 배경 위에 'JWT 디코드'라는 큰 글자와 header·payload·signature 세 조각, 만료 배지가 놓인 개발자용 표지 이미지.

서버가 401 Unauthorized를 던집니다. 토큰이 만료된 걸까요, 권한이 모자란 걸까요. 답은 토큰 안에 적혀 있는데, 길고 의미 없어 보이는 문자열이라 그냥 다시 로그인하고 넘어가기 쉽습니다. 그 문자열을 열어 보는 법부터 정리해 봅니다.

JWT는 암호화가 아니라 인코딩이다

JSON Web Token은 점(.)으로 이어진 세 조각입니다. header.payload.signature 순서로, 각 조각은 base64url로 인코딩돼 있습니다.

흔한 오해가 여기서 생깁니다. base64url은 암호화가 아니라 단순 인코딩이라, 비밀키 없이도 누구나 되돌려 읽을 수 있습니다. 즉 payload에 담긴 사용자 ID나 권한은 토큰을 가진 사람 누구에게나 보입니다. 비밀번호나 민감 정보를 payload에 넣으면 안 되는 이유입니다.

payload에 들어가는 클레임 읽기

payload 안의 각 항목을 클레임(claim)이라고 부릅니다. RFC 7519가 표준 클레임을 정의해 둬서, 이름만 알면 의미가 바로 읽힙니다.

클레임의미
iss발급자 (issuer)
sub토큰 주체 (subject, 보통 사용자 ID)
aud대상 (audience)
exp만료 시각 (expiration)
iat발급 시각 (issued at)
nbf활성 시작 시각 (not before)
jti토큰 고유 ID

exp, iat, nbf 세 개가 시간 클레임이고, 디버깅에서 가장 자주 보게 됩니다.

만료 확인: exp는 Unix epoch라 그냥 읽기 어렵다

exp가 만료 시각이긴 한데, 값이 1700003600 같은 숫자입니다. 사람이 읽으라고 만든 게 아니라 Unix epoch, 즉 1970년부터의 경과 초입니다.

그래서 도구가 환산을 대신합니다. PiPi Worlds JWT 디코더에 토큰을 넣으면 payload와 함께 시간 클레임이 ISO 형식으로 풀립니다. 예를 들어 iat: 17000000002023-11-14T22:13:20Z, exp: 17000036002023-11-14T23:13:20Z로 환산되고, 둘의 차이로 이 토큰의 유효 기간이 1시간임을 알 수 있습니다. 만료 시각이 현재보다 과거면 만료 배지가 붙습니다. 401이 떴을 때 이 배지 하나로 “만료라 갱신이 필요한지”가 바로 갈립니다.

디코드는 검증이 아니다

가장 중요한 구분입니다. 토큰을 디코드해 내용을 읽는 것과, 그 토큰이 진짜인지 검증하는 것은 다릅니다.

세 번째 조각인 서명(signature)은 발급자가 비밀키로 만든 값입니다. 위조되지 않았는지 확인하려면 같은 비밀키나 공개키로 서명을 다시 계산해 맞춰 봐야 합니다(RFC 7515). 디코더는 키를 받지도 보관하지도 않으므로 검증을 하지 않습니다. 따라서 디코드해서 보이는 payload는 “서버가 서명을 검증하기 전까지는 신뢰할 수 없는 값”으로 다뤄야 합니다. payload의 roleadmin이라고 적혀 있어도, 검증 없이 그 말을 믿으면 안 됩니다.

그 운영 토큰, 어디에 붙여넣고 있나요

여기서 보안 사고가 자주 납니다. 401을 디버깅하려고 운영 환경의 액세스 토큰을 아무 온라인 디코더에나 붙여넣는 경우입니다. 토큰 자체가 인증 수단인데, 입력값을 서버로 전송하는 사이트라면 그 순간 토큰이 제3자에게 넘어갑니다.

PiPi Worlds JWT 디코더는 디코딩이 전부 브라우저 안에서 실행됩니다. 토큰은 전송·기록·저장되지 않으므로 운영 토큰도 안심하고 살펴볼 수 있습니다. payload가 JSON이라 구조를 더 보기 좋게 펼치고 싶다면 JSON 포맷터를, 토큰을 이루는 base64url 인코딩 자체가 궁금하다면 Base64 도구를 함께 쓰면 됩니다.

자주 묻는 질문

JWT 디코더는 토큰이 유효한지도 검사하나요?
아니요. 디코더는 `exp` 클레임으로 만료 여부만 표시하고, 암호 서명 검증은 하지 않습니다. 토큰이 위조되지 않았는지 확인하려면 백엔드의 비밀키나 공개키로 서명을 검증해야 합니다. 디코드와 검증은 다른 단계입니다.
토큰 만료 시각은 어떻게 읽나요?
payload의 `exp` 클레임이 만료 시각인데, 값은 사람이 읽기 어려운 Unix epoch(초)입니다. JWT 디코더가 이를 ISO 형식으로 환산해 줍니다. `exp`에서 `iat`(발급 시각)를 빼면 토큰의 유효 기간을 알 수 있습니다.
payload는 암호화되어 있나요?
아니요. JWT의 header와 payload는 base64url로 인코딩된 JSON일 뿐이라 누구나 디코드해 읽을 수 있습니다. 암호화가 아니므로 비밀번호 같은 민감 정보를 payload에 넣으면 안 됩니다.
401 오류가 토큰 만료 때문인지 어떻게 아나요?
토큰을 디코드해 `exp`를 현재 시각과 비교하면 됩니다. 만료가 지났으면 갱신(refresh)이 필요한 상황이고, 만료 전인데도 거부된다면 권한(scope)이나 서명 검증 쪽 문제일 가능성이 높습니다.
실제 운영 토큰을 디코더에 붙여넣어도 되나요?
디코딩이 브라우저 안에서만 실행되는 도구라면 입력이 서버로 전송되지 않아 안전합니다. PiPi Worlds JWT 디코더가 그렇습니다. 다만 토큰을 다른 곳에 공유한 적이 있다면 폐기(revoke)하는 편이 안전합니다.

Sources

PiFl Labs 콘텐츠팀이 공개 출처를 토대로 작성하고, 발행 전 사내 검수를 거칩니다.

최종 검토:

도구로 돌아가기 →