exp
이 시각 이후에는 토큰을 거부해야 한다는 뜻입니다. 문제는 서버 시간, 프록시 시간, 사용자의 로컬 시간이 모두 다를 수 있다는 점입니다.
🔒 브라우저 내부 처리
JWT의 exp, nbf, iat 클레임을 어떻게 읽어야 하는지와, clock skew 때문에 자주 생기는 장애 패턴을 정리했습니다.
First Read
exp이 시각 이후에는 토큰을 거부해야 한다는 뜻입니다. 문제는 서버 시간, 프록시 시간, 사용자의 로컬 시간이 모두 다를 수 있다는 점입니다.
nbf이 시각 이전에는 토큰을 아직 쓰면 안 된다는 의미입니다. 발급 직후 호출에서 바로 실패하는 상황은 이 값과 clock skew를 먼저 의심해야 합니다.
iat언제 발급되었는지를 뜻하지만, 검증에 직접 쓰이지 않는 경우도 많습니다. 다만 디버깅할 때는 세 클레임을 같이 봐야 흐름이 맞습니다.
Common Failures
JWT는 보통 Unix 초 단위를 쓰는데, 프런트엔드 코드나 로그 뷰어가 밀리초로 착각하면 시간이 완전히 다르게 보입니다.
내용을 읽을 수 있다고 해서 유효한 토큰은 아닙니다. 외부 issuer 환경이라면 JWKS 기반 서명 검증이 별도로 필요합니다.
애플리케이션 서버와 인증 서버의 시간이 몇 초만 달라도 경계 구간에서 실패가 반복될 수 있습니다. 운영 문서에 허용 clock skew 기준을 적어두는 편이 좋습니다.
Workflow
exp, nbf, iat를 사람이 읽는 시각으로 다시 봅니다.Examples
입력
{
"sub": "user-123",
"iat": 1767225600,
"nbf": 1767225600,
"exp": 1767229200
}
결과
iat 발급 시각 2026-01-01 00:00:00 UTC
nbf 유효 시작 2026-01-01 00:00:00 UTC
exp 만료 2026-01-01 01:00:00 UTC
유효 기간 1시간
세 값 모두 초 단위 epoch입니다. 밀리초를 넣으면 수만 년 후로 해석되어 만료 검사가 무력화됩니다.
입력
현재 1767225600 · nbf 1767229200
결과
아직 사용할 수 없음 (1시간 뒤부터 유효)
Troubleshooting
서버 시계가 어긋난 경우가 가장 흔합니다. 발급 서버가 조금 빠르면 받는 쪽 기준으로 nbf가 아직 미래입니다. 대부분의 라이브러리가 clock skew 허용값(보통 30~60초)을 제공하니 그것을 먼저 확인하세요.
JWT 표준(RFC 7519)의 시간 클레임은 초 단위입니다. Date.now()를 그대로 넣으면 1000배가 되어 사실상 만료되지 않는 토큰이 발급됩니다. 보안 사고로 이어지는 실수라 발급 코드를 먼저 확인하세요.
JWT의 헤더와 페이로드는 Base64URL 인코딩일 뿐 암호화가 아닙니다. 누구나 읽을 수 있고 내용을 바꿔 다시 인코딩할 수도 있습니다. 서명 검증을 통과해야 신뢰할 수 있으며, 페이로드에 비밀 값을 담아서는 안 됩니다.