
JWT vs 세션 기반 인증 방식 비교 및 실무 대응 전략
✅ 인증 방식 개요
| 항목 | JWT (JSON Web Token) | 세션 기반 인증 |
|---|
| 방식 | 토큰을 클라이언트가 저장, 매 요청마다 헤더의 Authorization 필드에 담아 전송 | 세션 ID를 서버에 저장, 클라이언트는 쿠키로 보관 |
| 저장 위치 | 클라이언트 (로컬스토리지, 쿠키 등) | 서버 메모리 또는 세션 저장소 (Redis 등) |
| 상태성 | Stateless (무상태) | Stateful (상태 유지) |
| 확장성 | 서버 확장에 유리 | 서버 확장 시 세션 공유 필요 |
| 보안 | 탈취 시 위험. 위변조 방지 서명 필요 | 서버에만 정보가 있어 비교적 안전 |
| 로그아웃 처리 | 블랙리스트 등 별도 구현 필요 | 서버에서 세션 삭제 시 즉시 무효화 가능 |
🧩 JWT의 구조와 서명 검증 방식
✅ JWT 구성
JWT는 세 부분으로 구성되어 있음:
<Header>.<Payload>.<Signature>
- Header: 토큰 타입과 해싱 알고리즘 정보를 담음 (ex. HS256)
- Payload: 유저 정보와 클레임 (exp, sub 등)을 포함
- Signature: Header + Payload를 서버의 비밀 키로 서명한 값
예시:
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "1234567890",
"name": "John Doe",
"exp": 1710000000
}
✅ 서명(Signature) 생성 및 검증
서명 생성 방식 (서버):
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
검증 시 (서버):
- 클라이언트로부터 받은 JWT를 디코딩
- Header와 Payload를 사용하여 서버의
secret 키로 다시 서명 생성
- 생성된 서명과 클라이언트가 보낸 Signature가 일치하는지 비교
- ✅ 일치 → 유효한 토큰
- ❌ 불일치 → 위변조된 토큰 → 인증 거부
🔐 JWT 사용 시 예상되는 보안 문제와 해결 방안
1. Access Token 탈취 시 대응 불가
- 문제: Access Token이 탈취되면 유효기간 내 누구나 사용할 수 있음
- 해결:
- Access Token 유효기간을 짧게 설정 (ex. 15분)
- Refresh Token 도입
- Redis 기반 블랙리스트로 탈취 토큰 차단 (토큰 감지 로직 필요)
2. Refresh Token 탈취 시 무한 재발급
- 문제: Refresh Token이 탈취되면 공격자가 Access Token을 계속 재발급 가능
- 해결:
- Rotating Refresh Token 전략 적용 (1회 사용 후 폐기)
- 재사용 감지 시 탈취로 간주하여 차단
- IP, User-Agent 바인딩
- ✅ 예시: 구글, 카카오톡 등에서 "평소와 다른 장소에서 로그인되었습니다" 알림 발생
3. 로그아웃 불가 (Stateless 구조의 한계)
- 문제: 서버가 상태를 기억하지 않아 강제 로그아웃 어려움
- 해결:
- Redis 기반 블랙리스트 구현
- 로그아웃 시 Access Token을 등록하고 차단
4. 동시 로그인 제어 불가
- 문제: 하나의 계정으로 여러 기기에서 동시 로그인 가능
- 해결:
- 로그인 시 jti(UUID) 부여 → Redis 저장
- 요청 시 jti 검증 → 기존 jti 무효화
5. 토큰 크기 증가로 인한 성능 저하
- 문제: JWT는 세션 ID보다 길고, 매 요청마다 전송됨 → 트래픽 증가
- 해결:
- Payload에 최소한의 정보만 포함 (ex. userId, role)
- 민감 정보는 포함 금지
✅ 결론: JWT vs Session
- JWT 인증은 서버가 상태를 저장하지 않아 확장성과 분산 시스템에 유리하며, 모바일, API 기반 서비스에 적합합니다.
- 반면 세션 기반 인증은 서버에 상태를 저장하므로, 보안과 통제 측면에서 더 강력한 제어가 가능합니다.
- 실제 서비스에서는 두 방식을 적절히 조합하거나, 서비스 특성에 따라 선택하는 것이 중요합니다.