세션이란 사용자와 서버 간의 상태를 유지하기 위한 일련의 상호작용 또는 연결 상태를 의미한다.
웹 환경에서는 http로 주로 통신하는데, http 통신은 기본적으로 상태를 저장하지 않는 통신 방식이기 때문에 이를 해결하기 위해 세션이란 개념이 도입된다.
세션은 상태를 저장하기 위한 특정한 저장소라기 보다는 개념적인 것이라고 생각한다.
예를 들어서 세션은 스프링의 인터페이스인 HttpSession이 될 수도 있고, MySQL, Redis 등의 DB가 될 수도 있다.
세션은 유지하고 싶은 정보(상태)를 session id를 생성해 키/값 구조로 서버에 저장하는 식이다.
스프링부트 기반의 웹 어플리케이션을 개발하다 보면 쿠키에 JSESSIONID이 저장되는데, 이것은 스프링부트에 기본적으로 내장된 톰캣(was)가 세션을 유지하기 위해 JSESSIONID를 생성해 쿠키에 저장하기 때문이다.
여기서 헷갈릴 수 있는데 쿠키에 세션의 키/값이 저장되는 것이 아니다.
쿠키에는 서버에 있는 세션을 특정하는 ID가 저장되는 것이고, http 요청을 보내면 쿠키는 자동으로 요청에 담기기 때문에 쿠키에 저장된 sessionid로 서버의 세션을 찾아 사용하는 것이다.
세션은 클라이언트가 아닌 서버 측에 데이터를 저장하므로, 쿠키나 로컬 스토리지보다 상대적으로 보안성이 높다.
클라이언트에 노출되는 정보는 보통 세션 ID뿐이고 민감한 정보는 서버 내부에서만 관리되기 때문에 XSS나 클라이언트 조작 위험이 낮다.
쿠키는 개당 약 4KB 제한이 있는 반면, 세션은 서버 메모리 또는 외부 저장소(Redis, DB 등)를 사용하므로 상대적으로 더 많은 데이터를 저장할 수 있다.
예를 들어, 장바구니나 로그인 사용자 정보, 권한 정보 등 복잡한 구조의 데이터를 안전하게 저장하고 활용할 수 있다.
HTTP는 무상태(stateless) 프로토콜이지만, 세션을 통해 로그인 상태, 사용자 설정 등 지속적인 상태를 유지할 수 있다.
이는 인증 기반 서비스, 관리자 페이지, 쇼핑몰 등 사용자 경험이 중요한 웹 애플리케이션에 핵심적인 기능이다.
세션은 기본적으로 서버 메모리나 외부 저장소에 상태를 저장하므로, 사용자가 증가할수록 리소스 소비가 증가한다.
예를 들어 Spring에서 HttpSession을 메모리 기반으로 운영하면, 수만 명의 사용자가 동시에 접속할 경우 메모리 사용량이 급증해 OutOfMemoryError 등의 문제가 발생할 수 있다.
세션이 서버에 저장되는 구조라면, 로드 밸런싱 환경에서 세션이 분산되지 않고 특정 서버에 고정되는 sticky session 같은 문제가 발생한다.
이를 해결하기 위해 세션 클러스터링, 세션 공유 저장소(Redis, DB), JWT 기반 무상태 아키텍처 등을 도입해야 하며, 설계 복잡도와 인프라 부담이 증가한다.
세션은 수명(lifetime), 갱신 전략, 보안 설정(예: 세션 탈취 방지) 등을 별도로 관리해야 하며, 설정이 미흡하면 세션 고갈, 메모리 누수, 보안 취약점으로 이어질 수 있다.