
JWT의 정의
JSON 웹 토큰(JWT)은 JSON 객체 형태로 당사자 간에 정보를 안전하게 전송하는 간결하고 독립적인 방식을 정의하는 개방형 표준( RFC 7519 )이다. 이 정보는 디지털 서명되어 있으므로 검증 및 신뢰가 가능하다. JWT는 비밀 키( HMAC 알고리즘 사용) 또는 RSA 또는 ECDSA를 사용하는 공개/개인 키 쌍을 사용하여 서명할 수 있다.
JWT는 당사자 간 비밀 유지를 위해 암호화될 수 있지만, 여기서는 서명된 토큰 에 초점을 맞춘다. 서명된 토큰은 토큰에 포함된 클레임의 무결성을 검증할 수 있는 반면, 암호화된 토큰은 다른 당사자에게 해당 클레임을 숨긴다. 공개 키/개인 키 쌍을 사용하여 토큰에 서명하는 경우, 서명은 개인 키를 보유한 당사자만이 토큰에 서명했음을 증명한다.
JWT가 필요한 이유 (Session 기반 인증과의 차이점)
웹 애플리케이션에서 사용자 인증을 구현할 때 가장 흔히 떠올리는 방식은 세션(Session) 기반 인증이다. 그런데 왜 많은 개발자들이 JWT를 사용하고 있을까? 두 방식을 비교하면서 그 이유를 살펴보자.
Session 기반 인증 방식
- 사용자가 로그인하면 서버는 인증 정보를 바탕으로 세션을 생성하고, 세션 ID를 브라우저의 쿠키에 저장한다.
- 사용자는 이후 요청마다 쿠키에 포함된 세션 ID를 함께 보내고, 서버는 세션 ID로 저장된 정보를 찾아 인증을 처리한다.
- 서버는 로그인한 사용자마다 세션 정보를 메모리나 DB에 유지해야 한다.
장점
- 구현이 간단하고, 서버 쪽에서 세션을 관리하므로 보안이 비교적 강함
- 세션 무효화가 쉬움 (ex. 서버에서 세션 삭제)
단점
- 서버가 사용자 수만큼 세션을 저장해야 하므로 확장성이 떨어짐
- 분산 서버 환경(로드밸런싱)에서는 세션 공유를 위해 별도 설정이 필요 (세션 클러스터링, Redis 사용 등)
JWT 기반 인증 방식
- 로그인 성공 시 서버는 사용자 정보를 담은 JWT를 발급해서 클라이언트에게 전달한다.
- 클라이언트는 JWT를 로컬 스토리지나 쿠키에 저장하고, 이후 요청의 Authorization 헤더에 JWT를 담아 전송한다.
- 서버는 해당 JWT의 서명을 검증하고, 요청을 처리한다. 세션 저장이 필요 없다.
장점
- 서버는 세션을 저장할 필요가 없어 무상태(Stateless) 구조
- 서버 간 공유 없이도 인증 가능 → 분산 환경에서 유리
- 다양한 플랫폼(웹, 모바일 등)에서 동일하게 사용 가능
단점
- 토큰 자체에 정보가 들어있기 때문에 탈취 시 위험 (HTTPS 필수)
- 서버에서 토큰을 강제로 무효화하기 어려움
- 만료 전까지는 유효하므로 보안 사고 시 대응이 늦어질 수 있음
JWT 구조

JWT(JSON Web Token)는 세 부분으로 구성된 문자열이다. 이 세 부분은 점(.)으로 구분되며, 각각 Header, Payload, Signature 역할을 한다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikdlbnl1cyIsImlhdCI6MTUxNjIzOTAyMn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header
JWT의 헤더는 토큰의 타입과 서명에 사용할 알고리즘 정보를 담고 있다.
{
"alg": "HS256",
"typ": "JWT"
}
- alg: 서명 알고리즘 (예: HS256, RS256 등)
- typ: 토큰의 타입. 보통 "JWT"로 고정
이 내용은 Base64Url 인코딩되어 JWT의 첫 번째 부분이 된다.
Payload (페이로드)
페이로드는 실제 사용자 정보(클레임)가 담기는 부분이다. 이 정보는 암호화되지 않기 때문에 누구나 디코딩할 수 있다.
{
"sub": "1234567890",
"name": "Genyus",
"admin": true,
"iat": 1516239022
}
- sub(Subject): 사용자 ID
- name: 사용자 이름
- admin: 사용자 권한
- iat(Issued At): 발급 시간
JWT에서 사용할 수 있는 클레임은 다음과 같이 나뉜다:
| 등록 클레임 (Registered) | iss, exp, sub, aud, nbf, iat, jti 등 |
| 공개 클레임 (Public) | 사용자 정의 가능, 충돌 피하기 위해 URI 명시 권장 |
| 비공개 클레임 (Private) | 발급자-수신자 간의 커스텀 정보 |
Signature (서명)
서명은 토큰의 위변조를 방지하기 위해 사용된다.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
즉, 헤더와 페이로드를 인코딩한 후, 비밀 키로 서명한 값이 Signature다.
서버는 이 서명을 확인하여 토큰의 무결성을 검증한다.
JWT 발급 / 검증 예제
1. 로그인시 JWT 발급
사용자가 ID/PW로 로그인에 성공하면, 서버는 해당 사용자의 정보를 기반으로 JWT를 생성해서 응답으로 보낸다.
// Node.js 예시 (jsonwebtoken 라이브러리 사용)
const jwt = require('jsonwebtoken');
const user = { id: 1, name: 'Genyus' };
const secret = 'my_secret_key';
const token = jwt.sign(user, secret, { expiresIn: '1h' });
console.log(token);
// Spring Boot 예시 (jjwt 사용)
String token = Jwts.builder()
.setSubject("Genyus")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간
.signWith(SignatureAlgorithm.HS256, "my_secret_key")
.compact();
2. 클라이언트 저장 및 사용
- 발급된 토큰은 클라이언트 측에서 로컬 스토리지, 또는 쿠키에 저장한다.
- 이후 요청 시 Authorization 헤더에 Bearer <token> 형식으로 보낸다.
GET /api/userinfo HTTP/1.1
Authorization: Bearer eyJhbGciOi...
3. 서버에서 JWT 검증
서버는 요청 시 받은 JWT의 서명을 검증하고, 유효하면 해당 사용자로 인식한다.
const decoded = jwt.verify(token, secret);
console.log(decoded); // { id: 1, name: 'Genyus', iat: ..., exp: ... }
Claims claims = Jwts.parser()
.setSigningKey("my_secret_key")
.parseClaimsJws(token)
.getBody();
System.out.println(claims.getSubject()); // Genyus
보안 고려사항
JWT는 편리하지만, 민감한 정보를 다루기 때문에 반드시 보안에 신경 써야 한다.
HTTPS 필수
- JWT는 Payload가 암호화되지 않는다.
- Base64 인코딩된 정보는 누구나 디코딩 가능하므로, HTTPS 없이 전송하면 탈취 위험이 크다.
토큰 만료시간 설정
- exp 클레임을 활용해 토큰의 만료 시간을 짧게 설정하자.
- 예: 15분~1시간
- 짧은 토큰 + 리프레시 토큰 구조를 사용하는 게 일반적이다.
리프레시 토큰 사용
- 액세스 토큰은 짧게, 리프레시 토큰은 길게 유효하도록 설정
- 리프레시 토큰으로 만료된 액세스 토큰을 갱신
토큰 탈취 시 대응
- 로그아웃 처리가 어렵다
- 토큰 탈취 시 만료되기 전까지는 계속 유효
이를 보완하기 위해 다음 전략을 사용할 수 있다.
| 전략 | 설명 |
| 짧은 만료 시간 | 액세스 토큰 자체를 자주 바꾼다 |
| 리프레시 토큰 블랙리스트 | 서버에서 리프레시 토큰만 저장하고 무효화 가능하게 한다 |
| Redis나 DB로 블랙리스트 관리 | JWT 무효화 처리를 위한 블랙리스트 테이블 운영 |
기타 고려사항
- JWT에 민감한 정보(password, 주민번호 등)는 절대 포함하지 말 것
- 서명 키는 외부에 노출되지 않도록 .env 등에서 관리
- 필요 시 RS256 (비대칭키 방식) 도 검토
REFRENCE
JSON Web Token Introduction - jwt.io
Learn about JSON Web Tokens, what are they, how they work, when and why you should use them.
jwt.io
'백엔드' 카테고리의 다른 글
| [개념] 세션 기반 로그인 (1) | 2025.05.15 |
|---|---|
| [개념] 인증(Authentication) vs 인가(Authorization) (4) | 2025.05.15 |
| [개념] 소프트웨어 디자인 패턴과 MVC 패턴 (1) | 2025.04.04 |