Topic (오늘의 주제)
Session 기반 인증 vs Token(JWT) 기반 인증
Why (왜 사용하는가? 왜 중요한가?)
- 실무: 서비스의 규모(트래픽), 아키텍처(Monolithic vs MSA), 클라이언트 환경(Web vs App)에 따라 적합한 인증 방식을 선택해야 시스템 성능과 확장성을 보장할 수 있습니다.
- 구조적 의미: Stateful(상태 유지) 서버를 만들 것인가, Stateless(무상태) 서버를 만들 것인가를 결정하는 아키텍처의 핵심 기준이 됩니다.
- 면접 의도: 두 방식의 장단점과 동작 원리를 정확히 이해하고 있는지, 특히 확장성(Scale-out) 문제와 보안 취약점을 고려해 설계를 할 수 있는지 확인합니다.
Core Concept (핵심 개념 정리)
| 요소 | Session 기반 (Stateful) | Token 기반 (Stateless, ex: JWT) |
| 개념 정의 | 서버가 사용자의 로그인 정보(상태)를 **메모리나 DB(세션 저장소)**에 저장하고, 클라이언트에게는 Session ID만 주는 방식. | 서버가 정보를 저장하지 않고, 사용자 정보와 유효성을 담은 **암호화된 토큰(문자열)**을 발급하여 클라이언트가 이를 저장/제출하는 방식. |
| 저장 위치 | Server: 세션 저장소(메모리, Redis 등) Client: 쿠키 (Session ID만 보유) |
Server: 저장 안 함 (서명 검증만 함) Client: 로컬 스토리지, 쿠키 등 |
| 동작 흐름 | 1. 로그인 성공 → 서버가 세션 생성 및 ID 발급. 2. 응답 헤더(Set-Cookie)로 ID 전달. 3. 클라이언트는 쿠키에 ID를 담아 요청. 4. 서버는 ID로 저장소를 조회해 유저 확인. |
1. 로그인 성공 → 서버가 비밀키로 토큰(JWT) 생성. 2. 응답 바디/헤더로 토큰 전달. 3. 클라이언트는 헤더(Authorization)에 토큰 담아 요청. 4. 서버는 서명을 검증해 유효성 확인. |
| 장점 | 보안성: 서버가 세션을 강제 만료(로그아웃) 시킬 수 있음. 탈취 시 대응이 빠름. 단순함: 구현이 비교적 쉽고 데이터 크기가 작음. |
확장성: 서버가 상태를 저장하지 않으므로 스케일 아웃(서버 증설)이 매우 자유로움. 호환성: 모바일 앱, 웹 등 다양한 플랫폼 간 인증 공유 용이. |
| 단점 | 확장성: 서버가 늘어나면 세션 동기화(Clustering) 필요. 메모리: 동시 접속자가 많으면 서버 메모리 부족 우려. |
보안: 토큰이 탈취되면 만료될 때까지 막을 방법이 어려움(Blacklist 필요). 데이터: Payload가 커지면 네트워크 부하 증가. |
Interview Answer Version (면접 답변식 요약)
"가장 큰 차이는 **상태 유지 여부(Stateful vs Stateless)**입니다.
세션 방식은 서버가 로그인 정보를 메모리에 저장하므로 보안 관리가 쉽지만, 서버 확장 시 세션 불일치 문제가 발생해 별도의 저장소(Redis 등)가 필요합니다.
반면 **토큰 방식(JWT)**은 서버가 정보를 저장하지 않고 검증만 하므로 **서버 확장성(Scale-out)**과 MSA 환경에 적합하지만, 토큰 탈취 시 강제 만료가 어렵다는 단점이 있어 Refresh Token 전략을 함께 사용해야 합니다."
Practical Tip (사용시 주의할 점 or 활용 예)
1. 세션 방식의 확장성 문제 해결 (Session Clustering)
- 서버가 1대일 땐 문제없지만, 2대 이상으로 늘어나면(L4 로드밸런싱), A 서버에서 로그인한 사용자가 B 서버로 요청을 보낼 때 로그인이 풀리는 문제가 생깁니다.
- 해결: Redis나 Memcached 같은 외부 인메모리 DB를 세션 저장소로 사용하여 모든 서버가 세션을 공유하게 만듭니다. (Spring Session 라이브러리로 쉽게 구현 가능)
2. JWT 저장 위치 논쟁 (LocalStorage vs Cookie)
- LocalStorage:
- 장점: 사용하기 편함, CSRF 공격에 안전함.
- 단점: XSS(스크립트 삽입) 공격에 취약하여 토큰이 탈취될 수 있음.
- HttpOnly Cookie:
- 장점: 자바스크립트로 접근 불가하여 XSS에 안전함.
- 단점: CSRF(요청 위조) 공격에 취약함.
- 실무 권장: Refresh Token은 HttpOnly Cookie에 담아 보안을 높이고, **Access Token은 LocalStorage(혹은 메모리 변수)**에 담아 사용하는 하이브리드 전략을 많이 사용합니다.
3. JWT 로그아웃 문제
- JWT는 발급되면 서버가 제어할 수 없습니다. 사용자가 로그아웃 버튼을 눌러도, 해커가 탈취한 토큰은 유효기간 동안 사용 가능합니다.
- 해결: 로그아웃 시 해당 토큰의 잔여 유효시간만큼 Redis 같은 곳에 Blacklist로 등록하여, 요청이 올 때마다 차단하는 로직을 추가해야 완벽한 로그아웃이 됩니다.
예상 꼬리질문 정리
- Q: JWT를 썼는데 왜 Redis를 또 쓰나요? (Refresh Token)
- 핵심 키워드: Access Token의 유효기간을 짧게(30분) 가져가 보안을 챙기고, 긴 유효기간(2주)을 가진 Refresh Token을 Redis에 저장해두고 재발급 시 검증하기 위함입니다.
- Q: 세션 기반 인증에서 CSRF 공격을 어떻게 막나요?
- 핵심 키워드: Referrer 검증, CSRF Token 사용 (Spring Security는 기본적으로 CSRF Token을 요구함).
- Q: MSA(마이크로서비스) 환경에서 세션 방식을 쓰면 어떤 문제가 있나요?
- 핵심 키워드: 서비스 간 인증 정보를 공유하기 위해 모든 서비스가 공통된 세션 저장소를 바라봐야 하므로 결합도가 높아지고, 트래픽이 몰리면 세션 저장소가 병목지점(SPOF)이 될 수 있습니다.
'Archive > Daily Dev Q&A' 카테고리의 다른 글
| Daily Dev Q&A: JPA (0) | 2026.01.05 |
|---|---|
| Daily Dev Q&A: RESTful API 설계 원칙과 애매한 상황(Edge Case)의 현실적 해결 전략 (0) | 2025.12.31 |
| Daily Dev Q&A: Spring Security의 인증과 인가 (0) | 2025.12.31 |
| Daily Dev Q&A: @SpringBootApplication은 필수인가? (1) | 2025.12.30 |
| Daily Dev Q&A: Spring의 예외 처리 방식 (0) | 2025.12.29 |