JWT
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
— RFC 7519 표준 문서 중.
세션 저장소의 압박에서 서버를 구원해 준 stateless of savior. 하지만 한번 발급하면 만료 전까지는 변기 물 내려버리듯 삭제하기도 곤란한 시한폭탄
1. 개요
JWT(JSON Web Token)는 정보를 JSON 객체 형태로 안전하게 전송하기 위한 웹 표준 정의이다. 디지털 서명이 되어 있기 때문에 신뢰할 수 있으며, 주로 웹 애플리케이션의 인증(Authentication) 및 인가(Authorization) 과정에서 널리 쓰인다.
기존의 세션 기반 인증이 "서버 메모리에 사용자 정보를 올려두고 열쇠(Session ID)만 주는" 방식이었다면, JWT는 "사용자 신분증을 아예 클라이언트에게 들려 보내는" 방식이다. 덕분에 서버는 세션 저장소를 유지할 필요가 없어 가볍고 쾌활해졌지만, 그 대가로 클라이언트 보안이라는 또 다른 짐을 짊어지게 되었다.
2. JWT의 구조
JWT는 점(.)으로 구분된 세 개의 문자열로 이루어져 있으며, 대충 보면 외계어처럼 보이지만 사실은 그냥 Base64로 인코딩된 텍스트일 뿐이다.
2.1. Header (헤더)
토큰의 타입(JWT)과 서명에 어떤 암호화 알고리즘(예: HS256, RS256)이 사용되었는지를 담고 있다.
2.2. Payload (페이로드)
토큰에 담을 클레임(Claims) 정보들을 가지고 있다. 사용자 ID, 이름, 권한, 토큰 만료 시간(exp) 등이 들어간다. base64만 디코딩하면 누구나 속알맹이를 들여다볼 수 있으므로 민감한 정보는 절대 넣으면 안 된다.
2.3. Signature (서명)
인코딩된 헤더와 페이로드를 서버가 가진 비밀 키(Secret Key)로 해싱하여 만든다. 이 서명 덕분에 중간에 해커가 페이로드 정보를 조작하더라도 서버가 검증하는 과정에서 귓방망이를 날리며 "이거 조작된 토큰이네!" 하고 걸러낼 수
3. 관련 밈 및 드립
3.1. Payload에 비밀번호 넣는 빌런
보안 지식이 부족한 초보 개발자들이 흔히 저지르는 치명적인 실수 중 하나이다. "어차피 해싱돼서 암호처럼 보이는데 상관없겠지?" 하고 페이로드에 사용자의 비밀번호나 주민등록번호 등을 넣는 경우가 있다. 앞서 말했듯이 JWT의 페이로드는 1초 만에 평문으로 디코딩이 가능하므로, 이는 해커에게 지갑 비밀번호를 대문짝만하게 적어주는 것과 같다.1
3.2. Stateless라면서요? (결국 DB 뒤지는 엔딩)
JWT의 가장 큰 장점은 서버가 DB나 세션을 조회하지 않고 토큰 자체만으로 검증이 가능하다는(Stateless) 점이다. 하지만 실제 서비스를 운영하다 보면 "관리자가 특정 빌런 유저를 즉시 차단(Blacklist)"해야 하거나, "강제 로그아웃" 시켜야 하는 요구사항이 반드시 생긴다. 결국 블랙리스트 토큰을 저장하기 위해 Redis나 데이터베이스를 뒤지게 되며, 개발자들은 "이럴 거면 세션이랑 다른 게 뭐지...?"라며 깊은 철학적 번뇌에 빠진다.2
4. 여담
- 헤더 크기 비대화와 대역폭: 페이로드에 사용자 이름, 이메일, 프로필 사진 URL, 권한 목록 등을 왕창 집어넣다 보면 토큰의 길이가 기하급수적으로 늘어난다. 매 HTTP 요청마다 이 무거운 토큰이 헤더에 실려 나가기 때문에 네트워크 대역폭 낭비가 꽤 심해질 수 있다.
- Access vs Refresh 보관 분쟁: 해킹 위험을 줄이기 위해 보통 JWT의 유효기간은 15분~1시간 정도로 짧게 잡는다(Access Token). 그리고 토큰이 만료되면 조용히 새로운 토큰을 발급받기 위한 긴 유효기간의
Refresh Token을 함께 발급한다. 이 둘의 보관 장소(LocalStorage vs Cookie)를 두고 보안 커뮤니티에서는 매일같이 혈투가 벌어진다.3 - jwt.io 디버거 중독: 공식 사이트인
jwt.io에 가면 토큰을 붙여넣었을 때 실시간으로 페이로드를 디코딩해 보여주는 디버거를 제공한다. 개발 중 토큰 값이 이상하면 누구나 이 사이트를 켜서 토큰을 파싱하고 있다.