Cloud Visualizer
← 전체 목록
📋

Session

상태 관리서버가 사용자별 상태를 유지하는 연결 고리

세션(Session)은 서버가 개별 사용자의 상태를 일정 기간 동안 유지하는 메커니즘입니다. HTTP는 요청마다 독립적이어서 이전 요청의 맥락을 기억하지 않지만, 세션은 고유한 Session ID를 발급하고 그 ID에 연결된 데이터를 서버 측에 보관함으로써 여러 요청에 걸친 연속적인 상호작용을 가능하게 합니다. 사용자가 로그인하면 서버는 세션을 생성하고, 세션 ID를 쿠키로 클라이언트에 전달합니다. 이후 요청에서 브라우저가 이 쿠키를 보내면 서버는 세션 저장소에서 해당 사용자의 상태를 찾아 복원합니다.

아키텍처 다이어그램

점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다

왜 필요한가요?

쿠키 덕분에 브라우저와 서버 사이에 식별자를 주고받을 수 있게 됐습니다. 하지만 그 식별자에 무엇을 연결하고, 어디에 보관할지는 별개의 문제입니다. 사용자 정보를 쿠키 자체에 담으면 클라이언트가 값을 읽고 조작할 수 있고, 4KB 용량 제한도 걸립니다. 결제 진행 중인 주문 데이터나 관리자 권한 정보를 클라이언트 측에 그대로 두는 건 보안상 위험합니다. 반대로 서버가 상태를 갖지 않으면 매 요청마다 사용자가 누구인지, 무엇을 하고 있었는지를 처음부터 다시 파악해야 합니다. 인증을 반복하거나 모든 맥락을 매번 요청에 실어 보내야 하는 부담이 생깁니다. 필요한 건 클라이언트에는 가벼운 열쇠만 주고, 그 열쇠에 연결된 실제 데이터는 서버가 안전하게 보관하는 구조입니다.

왜 이런 방식이 등장했나요?

웹 애플리케이션이 정적 문서 전달을 넘어 로그인, 장바구니, 결제 같은 상태 기반 기능을 요구하기 시작하면서, 무상태 HTTP 위에 상태를 얹는 방법이 필요해졌습니다. 초기에는 URL에 세션 정보를 넣거나(URL Rewriting), 숨겨진 폼 필드로 데이터를 넘기는 방식도 쓰였지만 보안이 취약하고 관리가 번거로웠습니다. 서버 측 세션은 이 문제를 단순한 원칙으로 풀었습니다. 클라이언트에는 의미 없는 랜덤 문자열(Session ID)만 주고, 실제 데이터는 서버 메모리에 보관하는 것이었습니다. 이 패턴은 CGI 스크립트 시절부터 PHP, Java Servlet, ASP까지 서버 사이드 웹 프레임워크의 기본 기능으로 자리잡았고, 단일 서버에서는 거의 추가 설정 없이 동작했습니다.

안에서 어떻게 동작하나요?

세션의 핵심 메커니즘은 세 가지 단계로 나뉩니다. 첫째, 세션 생성입니다. 사용자가 로그인에 성공하면 서버는 충분히 긴 랜덤 문자열로 Session ID를 만들고, 그 ID를 키로 사용자 정보를 서버 측 저장소에 보관합니다. 이 ID는 Set-Cookie 헤더를 통해 클라이언트 브라우저에 전달됩니다. 둘째, 세션 조회입니다. 이후 브라우저가 요청을 보낼 때마다 쿠키에 Session ID가 자동으로 포함되고, 서버는 이 ID로 저장소를 조회해 해당 사용자의 상태를 복원합니다. 사용자 입장에서는 로그인 상태가 유지되고, 장바구니가 기억되고, 권한에 맞는 페이지가 보이는 것입니다. 셋째, 세션 만료와 정리입니다. 세션에는 일정 시간 동안 요청이 없으면 자동으로 삭제되는 타임아웃이 설정됩니다. 로그아웃하면 서버가 세션을 즉시 파기하고, 해당 Session ID는 더 이상 유효하지 않게 됩니다. 세션 저장소는 단일 서버에서는 프로세스 메모리로 충분하지만, 서버가 여러 대로 늘어나면 어느 서버에 요청이 가든 같은 세션을 찾을 수 있어야 합니다. 이때 Redis 같은 외부 저장소로 세션을 옮기거나, 로드 밸런서가 같은 사용자를 같은 서버로 보내는 고정 세션(sticky session) 방식을 씁니다.

무엇과 헷갈리나요?

세션과 JWT는 둘 다 HTTP 위에서 인증 상태를 유지하는 방법이지만, 상태의 위치가 다릅니다. 세션은 서버에 데이터를 두고 클라이언트에는 열쇠(Session ID)만 줍니다. JWT는 데이터 자체를 토큰에 담아 클라이언트가 들고 다니며, 서버는 서명을 검증해 위변조 여부만 확인합니다. 이 차이가 각각의 강점과 약점을 만듭니다. 세션은 서버가 상태를 직접 관리하기 때문에 특정 사용자의 세션을 즉시 무효화할 수 있습니다. 관리자 강제 로그아웃, 동시 로그인 제한 같은 기능이 자연스럽습니다. 대신 서버가 세션 저장소를 유지해야 하고, 서버가 여러 대일 때 저장소를 공유하는 문제가 생깁니다. JWT는 서버에 상태를 두지 않아서 서버 확장이 간단합니다. 하지만 한 번 발급한 토큰은 만료될 때까지 서버에서 취소하기 어렵습니다. 로그아웃을 서버 측에서 강제하려면 별도의 블랙리스트를 관리해야 하고, 그 순간 서버에 상태가 생기면서 JWT의 장점이 희석됩니다. 실제로는 '세션이냐 JWT냐'보다 '이 시스템이 즉시 무효화가 중요한가, 서버 무상태가 중요한가'를 먼저 따지는 것이 판단에 도움이 됩니다.

언제 쓰나요?

세션은 전통적인 서버 렌더링 웹 애플리케이션에서 인증과 상태 관리의 기본 도구입니다. 관리자 페이지에서 사용자를 강제 로그아웃시키거나, 동시 접속을 감지해 이전 세션을 만료시키는 기능은 서버가 세션을 직접 관리하기 때문에 가능합니다. 서버가 한 대일 때는 프로세스 메모리에 세션을 두면 별도 설정 없이 빠르게 동작합니다. 하지만 서비스가 커져서 서버를 추가하면 '사용자가 서버 A에서 로그인했는데 다음 요청이 서버 B로 갔을 때 세션을 못 찾는' 문제를 만나게 됩니다. 이 시점에서 Redis처럼 모든 서버가 공유할 수 있는 외부 세션 저장소를 도입하거나, 로드 밸런서에서 같은 사용자를 같은 서버로 고정하는 전략을 선택해야 합니다. 세션에 담는 데이터의 크기도 운영에서 고려할 지점입니다. 세션에 너무 많은 데이터를 넣으면 저장소 부하가 커지고, 세션 직렬화와 역직렬화 비용도 늘어납니다. 인증 정보와 최소한의 상태만 세션에 두고, 나머지는 필요할 때 데이터베이스에서 가져오는 것이 일반적인 지침입니다.

로그인 인증권한 관리다단계 폼장바구니
Official Docs

더 깊게 보기

현재 페이지의 개념 설명을 본 뒤 공식 문서로 바로 이동합니다.

web-dev