JWT 는 header.payload.signature 세 부분을 Base64URL 로 인코딩한 것이라 서명 검증 없이 내용만 보는 데는 base64 와 json 만 있으면 된다. 추가 패키지를 설치할 수 없는 서버에서 토큰의 만료 시각 등을 확인할 때 쓴다.
import base64
import json
from datetime import datetime, timezone
def decode_jwt(token: str) -> dict:
parts = token.split(".")
if len(parts) != 3:
raise ValueError("유효하지 않은 JWT 형식")
def decode_part(part: str) -> dict:
part += "=" * (-len(part) % 4) # Base64URL 패딩 보정
return json.loads(base64.urlsafe_b64decode(part))
header = decode_part(parts[0])
payload = decode_part(parts[1])
for field in ("exp", "iat", "nbf"): # 표준 시간 클레임
if field in payload:
payload[f"{field}_readable"] = datetime.fromtimestamp(
payload[field], tz=timezone.utc
).strftime("%Y-%m-%d %H:%M:%S UTC")
return {"header": header, "payload": payload}
if __name__ == "__main__":
import sys
result = decode_jwt(sys.argv[1])
print(json.dumps(result, indent=2, ensure_ascii=False))
exp · iat · nbf 는 Unix epoch 초 단위다. datetime.fromtimestamp(ts, tz=timezone.utc) 는 UTC, datetime.fromtimestamp(ts) 는 서버 로컬 시간(KST 면 UTC+9)으로 바꾼다.
from datetime import datetime, timezone
exp = 1772085503
print(datetime.fromtimestamp(exp, tz=timezone.utc).strftime('%Y-%m-%d %H:%M:%S %Z')) # 2026-02-25 03:38:23 UTC
print(datetime.fromtimestamp(exp).strftime('%Y-%m-%d %H:%M:%S')) # 2026-02-25 12:38:23 (KST)
이 코드는 서명을 검증하지 않으므로 신뢰 판단에는 쓰지 않는다.