1. 배경 (Context)
기존에 JSP나 Thymeleaf(SSR)로 개발할 때는 HttpSession을 이용해 로그인 처리를 했다. 하지만 최근 수업에서 Spring Boot로 REST API 서버를 구축하면서 "REST API는 세션을 사용하지 않는다"는 내용을 배웠다.
여기서 두 가지 큰 의문이 생겼다.
- "세션을 안 쓰면 도대체 무엇을 쓰는가?"
- "멀쩡한 세션을 두고 왜 굳이 다른 방식을 쓰는가?"
이 의문을 해결하기 위해 HTTP의 특성과 상태 관리 주체의 변화(Session vs Token)에 대해 정리해 본다.
2. 핵심 오해 바로잡기: 로그인 흐름
가장 헷갈렸던 부분이다. 세션 방식이나 토큰 방식이나 처음 로그인하는 순간은 100% 동일하다. 차이는 "응답(Response)"과 "그 이후의 요청"에서 발생한다.
🚫 잘못된 생각
- 로그인 요청: ID + PW + Token (X) -> 토큰은 아직 없으므로 불가능!
✅ 올바른 흐름 (REST API / Token 기준)
- 로그인 할 때 (최초 1회)
- Client ➡️ Server: ID, PW를 보냄.
- Server: ID/PW 확인 후, 유저 정보를 암호화하여 **Token(영수증/출입증)**을 발행해 응답함.
- 로그인 성공 후 (글쓰기, 조회 등)
- Client ➡️ Server: 더 이상 ID/PW를 보내지 않음. 발급받은 Token만 헤더에 넣어서 보냄.
- Server: 토큰의 서명(Signature)만 검증하여 유효하면 통과.
3. 왜 상태 관리가 필요한가? (HTTP의 특성)
HTTP 프로토콜은 근본적으로 무상태성(Stateless), 즉 "기억 상실증" 환자다.
- 서버는 클라이언트의 직전 요청을 기억하지 못한다.
- 로그인 직후에 마이페이지를 눌러도 서버는 "너 누구니?"라고 묻는다.
이 연결 고리를 유지하기 위해 "상태(State)를 어디에 저장하느냐"에 따라 기술이 나뉜다.
4. 과거의 방식: Session (Stateful)
주로 SSR(Server Side Rendering) 환경에서 사용된다.
- 비유: 목욕탕 락커 키
- 동작 원리:
- 입장(로그인): 서버는 유저 정보를 **서버 메모리(창고)**에 저장하고, 번호가 적힌 **세션 ID(락커 키)**를 발급한다.
- 보관: 클라이언트는 이 세션 ID를 쿠키에 저장한다.
- 이용: 요청 때마다 세션 ID를 보여주면, 서버가 자기 메모리를 뒤져서 유저를 찾는다.
- 단점: 접속자가 늘어나면 서버 메모리가 부족해진다. 서버가 여러 대일 경우 세션 공유(Session Clustering)가 까다롭다.
5. 요즘 방식: Token (Stateless)
주로 SPA(React/Vue) + REST API 환경에서 사용된다.
- 비유: 여권과 비자
- 동작 원리:
- 입장(로그인): 서버는 "난 내 메모리에 널 기억하지 않을 거야"라며, 유저 정보가 암호화된 **토큰(증명서)**을 발급해서 클라이언트에게 준다. (서버 저장 X)
- 보관: 클라이언트는 토큰을 로컬 스토리지나 쿠키에 직접 잘 보관한다.
- 이용: 요청 때마다 토큰을 헤더에 붙여 보낸다. 서버는 토큰이 위조되었는지만 수학적으로 검증한다.
- REST API에 적합한 이유:
- 서버 확장성(Scalability): 서버를 1대에서 100대로 늘려도 상관없다. 서버끼리 정보를 공유할 필요 없이, 들어오는 토큰만 검사하면 되기 때문이다.
- 플랫폼 독립성: 웹뿐만 아니라 앱(Android/iOS)에서도 공통으로 사용할 수 있다.
6. 비교 요약 (Session vs Token)
| 구분 | Session (Stateful) | Token (Stateless) |
| 상태 저장 위치 | 서버의 메모리 | 클라이언트 (브라우저/앱) |
| 인증 수단 | 의미 없는 문자열 (Session ID) | 정보가 담긴 암호화 문자열 (JWT) |
| 서버 부담 | 높음 (사용자 수만큼 메모리 필요) | 낮음 (검증 연산만 수행) |
| 확장성 (Scale-out) | 나쁨 (세션 불일치 문제 발생) | 좋음 (서버 무한 증설 가능) |
| 적합한 환경 | 전통적인 웹 (관공서, 사내 시스템) | 대용량 트래픽, MSA, 앱/웹 동시 지원 |
7. 결론 (Lesson Learned)
"REST API로 가면 세션이 필요 없다"는 말의 본질은 "서버가 짊어지던 '기억의 부담'을 클라이언트에게 넘겨버렸다"는 것이다.
- Session: 서버가 "내가 기억할게." (보안 제어 유리, 확장성 불리)
- Token: 서버가 "네가 가지고 다녀." (확장성 유리, 보안 제어 까다로움)
이를 통해 서버는 더 가벼워지고, 무한히 확장 가능한 구조(Stateless)를 갖추게 된다
'Archive > TIL' 카테고리의 다른 글
| [TIL] 웹 데이터의 변신과 여행: 직렬화부터 JWT 저장까지 (0) | 2025.12.29 |
|---|---|
| [TIL] JPA 영속성 전이와 고아 객체: Cascade vs OrphanRemoval 정리 (0) | 2025.12.16 |
| [TIL] 리액트 핵심 이론 정리: 제이쿼리 차이, 클로저, 비동기 (0) | 2025.12.05 |
| [TIL] 리액트 라우팅과 전역 상태 관리: Router & Context API (1) | 2025.12.02 |
| [TIL] 리액트 필수 개념 정리: 콜백 함수, 캡슐화, AJAX (0) | 2025.11.26 |