🤖 AI 생성 콘텐츠 — 이 글은 AI가 자료를 수집하고 초안을 작성했으며, 발행 전 누슘 운영자가 검수했습니다.
JWT는 내용을 읽을 수 있다고 진짜가 되는 토큰이 아닙니다. 서명 알고리즘·발급자·대상·만료·토큰 종류를 함께 검증해야 하는 이유와 실무 체크리스트를 정리합니다.
JWT를 점으로 나눠 디코딩했더니 사용자 ID와 역할이 잘 보입니다. 여기서 “정상 토큰이네”라고 결론 내리면 위험합니다. 디코딩은 봉투를 펼쳐 글자를 읽은 것뿐입니다. 검증은 봉인과 발신자, 받는 사람, 유효기간까지 확인하는 일입니다.
목차
- JWT는 무엇이고 무엇이 아닌가?
- 서명 검증은 어떻게 동작하나?
- 꼭 확인해야 할 5가지
- 안전한 운영은 어떻게 설계하나?
JWT는 무엇이고 무엇이 아닌가?
RFC 7519는 JWT를 URL에 안전하게 담을 수 있는 “클레임” 표현 형식으로 정의합니다. 클레임은 sub, iss, aud, exp처럼 토큰에 적힌 주장입니다. 보통 서명된 JWT는 점으로 구분된 세 부분을 가집니다.
- 헤더: 어떤 유형과 알고리즘을 썼는지
- 페이로드: 사용자·발급자·만료 같은 클레임
- 서명: 앞의 두 부분이 바뀌지 않았는지 확인하는 값
헤더와 페이로드는 흔히 Base64url로 인코딩됩니다. 암호화가 아닙니다. 누구나 읽을 수 있으므로 비밀번호나 주민번호 같은 비밀을 넣으면 안 됩니다. JWT는 그릇이고, 서명·암호화 여부는 사용 방식에 달려 있습니다.

서명 검증은 어떻게 동작하나?
서명된 토큰을 받으면 서버는 합의된 키와 알고리즘으로 헤더·페이로드의 서명을 다시 계산하거나 공개키로 확인합니다. 값이 맞으면 “발급 후 이 내용이 바뀌지 않았고 해당 키를 가진 주체가 서명했다”는 근거가 생깁니다.
하지만 서명만 맞아도 끝이 아닙니다. 진짜 호텔 카드키라도 다른 호텔 문에는 쓰면 안 됩니다. 그래서 발급자와 대상 서비스를 함께 확인해야 합니다.
꼭 확인해야 할 5가지
RFC 8725는 JWT 구현에서 반복된 공격을 바탕으로 최소 보안 관행을 제시합니다.
| 검증 항목 | 놓치면 생기는 문제 |
|---|---|
| 허용 알고리즘 고정 | 공격자가 헤더의 알고리즘 선택을 바꿀 수 있음 |
| 모든 암호 연산 성공 확인 | 실패한 서명이나 복호화 결과를 받아들일 수 있음 |
iss 발급자 확인 |
다른 발급자의 토큰을 내 서비스가 수용 |
aud 대상 확인 |
다른 API용 토큰을 내 API에서 재사용 |
exp 등 시간 확인 |
만료된 토큰이 계속 살아남음 |
여기에 토큰 종류도 분리해야 합니다. 액세스 토큰과 ID 토큰이 비슷하게 생겼다고 같은 검증 규칙을 쓰면 “교차 JWT 혼동”이 생길 수 있습니다. RFC 8725는 명시적 타입을 사용하고 서로 다른 종류의 JWT에 상호 배타적인 검증 규칙을 두라고 권고합니다.
가장 중요한 한 줄은 이것입니다. 토큰이 스스로 제안한 알고리즘을 그대로 믿지 마세요. 서버 설정에서 허용 알고리즘을 고정하고 라이브러리가 그것만 받게 해야 합니다.

안전한 운영은 어떻게 설계하나?
토큰 검증 코드 한 곳만 고쳐서는 부족할 수 있습니다.
- 검증 라이브러리를 직접 만들지 말고 유지보수되는 검증 라이브러리를 씁니다.
- 키 ID(
kid)로 키를 찾을 때 외부 입력이 파일 경로나 임의 URL로 이어지지 않게 합니다. - 키 교체 기간에는 새 키와 이전 키를 제한된 시간 동안만 함께 제공합니다.
- 액세스 토큰은 짧게, 갱신 토큰은 별도 저장·회수 정책으로 관리합니다.
- 로그에는 전체 JWT를 남기지 않습니다. 토큰은 인증 정보이자 개인정보 묶음일 수 있습니다.
- 브라우저 저장 위치를 정할 때 XSS와 CSRF 위협을 함께 봅니다.
JWT는 서버 세션을 없애는 마법이 아닙니다. 로그아웃 즉시 무효화, 계정 정지, 키 유출 대응이 필요하면 서버 상태나 회수 목록이 다시 필요할 수 있습니다.
자주 묻는 질문 (FAQ)
Q. jwt.io에서 내용이 보이면 토큰이 유출된 건가요? A. 서명된 JWT의 헤더와 페이로드는 원래 읽을 수 있는 경우가 많습니다. 문제는 그 안에 비밀정보를 넣었거나, 토큰 자체가 탈취돼 인증에 재사용되는 경우입니다.
Q. 서명만 맞으면 로그인 사용자로 믿어도 되나요?
A. 아닙니다. 발급자(iss), 대상(aud), 만료(exp)와 서비스가 요구하는 클레임을 함께 검증해야 합니다. 다른 서비스용 진짜 토큰도 내 서비스에서는 거절해야 합니다.
Q. JWT는 암호화되어 있나요? A. JWT 형식 자체가 암호화를 뜻하지 않습니다. JWS로 서명만 했다면 내용은 읽을 수 있고, 기밀성이 필요하면 적절한 JWE 또는 별도 보호 수단을 설계해야 합니다.
Q. JWT를 로컬스토리지에 저장해도 되나요? A. 단순한 정답은 없습니다. 로컬스토리지는 자바스크립트가 읽을 수 있어 XSS에 민감하고, 쿠키는 속성 설정과 CSRF 방어가 중요합니다. 애플리케이션 위협 모델에 맞춰 선택해야 합니다.
마치며
JWT 보안의 핵심은 “토큰을 읽었다”가 아니라 “우리 서비스가 정한 규칙으로 검증했다”입니다. 알고리즘, 서명, 발급자, 대상, 시간, 종류를 한 묶음으로 보세요. 하나라도 빠지면 멀쩡해 보이는 가짜 신분증이 문을 열 수 있습니다.
여러분의 인증 미들웨어는 어떤 항목을 검사하나요? 누슘 댓글에서 체크리스트와 경험을 나눠 주세요.
참고자료
- IETF RFC 7519 — JSON Web Token
- IETF RFC 8725 — JSON Web Token Best Current Practices
- OWASP — JSON Web Token Cheat Sheet for Java
태그: #JWT #토큰 #인증 #RFC7519 #RFC8725 #서명검증 #issuer #audience

댓글을 남기려면 로그인이 필요합니다.
로그인하고 댓글 남기기