쿠키와 세션 — HTTP 상태 관리 메커니즘
HTTP는 무상태(Stateless) 프로토콜이지만, 로그인 상태를 유지해야 합니다. 쿠키와 세션은 이 문제를 해결하는 가장 기본적인 방법입니다.
쿠키 (Cookie)
서버가 브라우저에 저장하는 작은 데이터 입니다. 이후 요청마다 자동으로 서버에 전송됩니다.
1. 서버 → 브라우저:
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
2. 이후 브라우저 → 서버 (자동 첨부):
Cookie: session_id=abc123
쿠키 보안 속성
| 속성 | 설명 |
|---|---|
| HttpOnly | JavaScript에서 접근 불가 (XSS 방어) |
| Secure | HTTPS에서만 전송 |
| SameSite=Strict | 같은 사이트 요청에만 전송 (CSRF 방어) |
| SameSite=Lax | GET 링크 클릭은 허용, POST는 차단 |
| SameSite=None | 크로스사이트 허용 (Secure 필수) |
| Domain | 쿠키 전송 범위 |
| Max-Age/Expires | 만료 시간 |
세션 (Session)
서버 측에 상태를 저장 하고, 쿠키에는 세션 ID만 저장합니다.
로그인 과정:
1. 클라이언트: POST /login (ID/PW)
2. 서버: 세션 생성 (session_id → {user: "kim", role: "admin"})
3. 서버 → 클라이언트: Set-Cookie: session_id=abc123
이후 요청:
1. 클라이언트: Cookie: session_id=abc123
2. 서버: 세션 저장소에서 abc123 조회 → 사용자 정보 확인
세션 저장소
| 저장소 | 장점 | 단점 |
|---|---|---|
| 서버 메모리 | 빠름 | 서버 재시작 시 소멸, 수평 확장 어려움 |
| Redis | 빠름, 서버 간 공유 | 외부 의존성 |
| DB | 영속성 | 느림 |
쿠키+세션 vs 토큰(JWT)
| 항목 | 세션 기반 | 토큰 기반 (JWT) |
|---|---|---|
| 상태 저장 | 서버 (세션 저장소) | 클라이언트 (토큰 자체) |
| 확장성 | 세션 공유 필요 | Stateless → 확장 용이 |
| 로그아웃 | 세션 삭제로 즉시 | 토큰 만료까지 유효 (블랙리스트 필요) |
| 보안 | 세션 ID 탈취 위험 | 토큰 탈취 위험 |
핵심 포인트
- 세션과 쿠키의 관계: 세션 ID를 쿠키에 저장하여 전달
- 서버 수평 확장 시 세션 문제: Sticky Session 또는 Redis 같은 외부 세션 저장소 필요
- SameSite 쿠키: CSRF 방어의 현대적 방법
정리
쿠키+세션은 HTTP 상태 관리의 전통적인 방법이고, JWT는 Stateless한 대안입니다. 각각의 장단점을 이해하고 상황에 맞게 선택하는 것이 중요합니다.