[인증/인가] Session, 왜 쿠키만으로는 부족했을까?
이전 글에서는 Cookie에 대해 알아보았다.
쿠키는 HTTP의 무상태성을 보완하는 가장 기본적인 방법이다.
서버는 상태를 기억하지 않지만, 쿠키를 통해 클라이언트가 상태를 대신 보관한다.
하지만 한 가지 질문이 남는다.
“사용자 인증 정보까지 클라이언트에 저장해도 괜찮을까?”
쿠키는 클라이언트(=브라우저)에 저장된다.
그리고 매 요청마다 자동으로 서버로 함께 전송된다.
편리하지만, 동시에 위험하다.
이 한계를 보완하기 위해 등장한 개념이 바로 Session이다.
Session이란?
사용자에 대한 상태 정보를 서버 측에서 저장하고 관리하는 방식이다.
쿠키가 ‘클라이언트 저장 방식’이라면, 세션은 ‘서버 저장 방식’이다.
서버는 사용자의 첫 요청이 들어오면 고유한 Session ID를 생성한다.
그리고 해당 ID를 기준으로 사용자 정보를 서버 메모리(또는 별도의 저장소)에 보관한다.
클라이언트는 실제 사용자 정보가 아니라, 오직 Session ID만 쿠키에 저장한다.
중요한 데이터는 서버에 두고,
클라이언트는 그 데이터에 접근하기 위한 식별자만 가진다.
왜 Session이 필요했을까?
쿠키는 클라이언트에 저장된다.
따라서 다음과 같은 위험이 존재한다.
- 값 변조 가능성
- 네트워크 스니핑
- XSS를 통한 탈취
물론 HttpOnly, Secure, SameSite 같은 옵션으로 보완할 수 있다.
하지만 이는 보호 장치일 뿐, 구조 자체를 바꾸지는 못한다.
| 민감한 데이터를 클라이언트에 저장하는 구조는 본질적으로 위험 요소를 가진다. |
그래서 등장한 접근이 있다.
“그렇다면 중요한 정보는 서버에 저장하면 되지 않을까?”
이 질문에 대한 답이 바로 Session이다.
Session 특징
1. 서버 측 저장 방식
- 사용자 정보는 서버에서 관리된다.
- 클라이언트에는
Session ID만 저장된다. - 실제 데이터는 외부에 직접 노출되지 않는다.
2. 세션 ID 기반 식별
서버는 클라이언트를 구분하기 위해 고유한 Session ID를 발급한다.
- 브라우저 단위로 저장된다.
- 동일 브라우저의 여러 탭에서는 공유된다.
- 브라우저를 종료하면 일반적으로 세션 쿠키는 제거된다.
- 서버에서 강제로 만료시킬 수 있다.
3. 만료 시간 관리
세션은 일정 시간 동안 요청이 없으면 자동 만료되도록 설정할 수 있다.
- 30분 동안 활동이 없으면 자동 로그아웃
- 금융 서비스처럼 보안이 중요한 경우 더 짧게 설정
4. 저장 용량 제약이 비교적 적다
쿠키는 약 4KB 제한이 있지만,
세션은 서버 자원이 허용하는 범위 내에서 비교적 자유롭다.
하지만 이것은 장점이자 동시에 서버 부담 요소가 된다.
Session과 Cookie의 차이점
| 구분 | Cookie | Session |
|---|---|---|
| 저장 위치 | 클라이언트 | 서버 |
| 저장 데이터 | 실제 데이터 | Session ID |
| 보안성 | 상대적으로 낮음 | 상대적으로 높음 |
| 서버 자원 사용 | 없음 | 있음 |
| 속도 | 빠름 | 서버 처리 필요 |
둘의 핵심 차이는 “저장 위치”이다.
쿠키는 데이터를 직접 보관한다.
세션은 데이터를 서버에 보관하고, 식별자만 전달한다.
그렇다면 Session만 사용하면 되는거 아니야?
겉보기에는 Session이 더 안전해 보인다.
그렇다면 모든 상태 관리를 세션으로 처리하면 되지 않을까?
그렇지 않다.
세션은 서버 자원을 사용한다.
- 사용자 수 증가 ➔ (서버) 메모리 사용량 증가
- 동시 접속자 수 증가 ➔ 서버 부하 증가
- 서버 확장 ➔ 세션 공유 문제 발생
즉, 세션은 보안을 강화했지만 확장성과 비용 측면에서 또 다른 설계 문제가 발생한다.
그래서 실제 서비스에서는 쿠키와 세션을 용도에 따라 함께 사용한다.
- 로그인 상태 유지 ➔ 세션
- 다크모드 설정 ➔ 쿠키
- 팝업 여부 (
오늘 하루 그만 보기) ➔ 쿠키
세션 동작 순서
1
2
3
4
5
6
7
클라이언트가 서버에 요청을 보낸다. (Session ID 없음)
서버는 Session ID 존재 여부를 확인한다.
없으면 새로운 Session ID를 생성한다.
서버는 세션 저장소에 사용자 정보를 저장한다.
Session ID를 쿠키에 담아 클라이언트에게 전달한다.
이후 요청부터는 쿠키에 담긴 Session ID가 함께 전송된다.
서버는 해당 ID로 세션 정보를 조회해 요청을 처리한다.
여기서 중요한 점이 있다.
세션은 쿠키를 사용하지 않는 기술이 아니다.
세션은 쿠키를 식별자 전달 수단으로 활용하는 방식이다.
이 부분을 이해해야 쿠키와 세션의 관계를 정확히 설명할 수 있다.
세션의 장・단점
장점
- 사용자 정보가 서버에 저장되어 비교적 안전하다.
- 요청 시마다 DB에서 인증 정보를 조회할 필요가 없다.
- 로그인 상태 관리가 명확하다.
- 서버에서 강제 로그아웃 처리가 가능하다.
단점
1. 서버 메모리 부담
세션은 사용자 수에 비례해 메모리 사용량이 증가한다.
대규모 트래픽 환경에서는 서버 부하가 증가하므로, 메모리 관리 전략이 필요하다.
2. 확장성 문제
로드 밸런싱 환경에서 문제가 발생한다.
- A 서버에 저장된 세션
- B 서버는 해당 세션을 모른다.
이로 인해 세션 불일치, 즉 정합성 문제가 발생한다.
3. 저장소 비용
Redis와 같은 인메모리 저장소를 사용할 경우 메모리 비용이 증가한다.
관계형 DB에 저장하면 빈번한 읽기/쓰기 작업으로 인해 성능 부담이 발생할 수 있다.
🥷 세션 하이재킹 (Session Hijacking)
정상 사용자의 Session ID를 탈취해 공격자가 해당 사용자처럼 행동하는 공격이다.
공격 흐름은 다음과 같다.
- 공격자가 XSS, 네트워크 스니핑 등의 방법으로
Session ID를 탈취한다. - 탈취한
Session ID를 포함해 서버에 요청을 보낸다. - 서버는 이를 정상 사용자로 인식한다.
세션 구조 자체는 안전하지만 Session ID가 노출되는 순간, 사용자의 권한은 그대로 공격자에게 넘어간다.
어떻게 방어할 수 있을까?
HttpOnly설정 ➔ XSS로부터 쿠키 보호Secure옵션 사용 ➔ HTTPS 강제SameSite설정 ➔ 교차 사이트 요청 시 쿠키 전송 제한- 짧은 세션 만료 시간 설정 ➔ 탈취 위험 시간 최소화
- 재인증 (2FA) 적용 ➔ 세션 탈취 후 피해 차단
- ex) 패스키 및 하드웨어 보안 키, 문자 메시지 또는 전화로 인증 코드 받기
- 사용 후 즉시 로그아웃 ➔ 세션 노출 시간 최소화
세션은 서버에 저장되지만, Session ID는 일반적으로 쿠키를 통해 전달된다.
따라서 쿠키 보호는 곧 Session ID 보호와 직결된다.
마무리
쿠키는 상태를 저장하는 가장 단순한 방법이다.
세션은 그 한계를 보완하기 위해 등장한 방식이다.
하지만 세션 역시 완전한 해결책은 아니다.
특히 서버가 여러 대로 확장되는 순간, 또 다른 설계 문제가 발생한다.
“서버가 여러 대라면, 세션은 어디에 저장해야 할까?”
“각 서버는 어떻게 동일한 세션을 공유할 수 있을까?”
Sticky Session, Session Clustering, Session Storage 분리 (In-Memory DB)
이 세 가지 방식을 중심으로 다중 서버 환경에서 세션을 어떻게 관리하는지 살펴보자.
