로그인을 공부할 때 가장 먼저 헷갈렸던 것은 세션과 쿠키의 역할이었다. 둘은 함께 사용되는 경우가 많지만 같은 것은 아니다.
HTTP는 기본적으로 상태가 없는 프로토콜이다. 이전 요청을 보낸 사용자와 다음 요청을 보낸 사용자가 같은 사람인지 HTTP 자체만으로는 알 수 없다.
첫 번째 요청: 로그인했어요.
두 번째 요청: 상품 목록을 보여주세요.
두 요청이 같은 브라우저에서 전송됐더라도 서버가 이를 연결할 별도의 장치가 필요하다. 이때 사용하는 방법 중 하나가 세션이다.
세션은 서버와 클라이언트의 네트워크 연결이 계속 유지되는 상태가 아니다. 서로 독립적인 HTTP 요청들을 같은 사용자에게서 온 요청으로 묶어 주는 논리적인 상태에 가깝다.
세션 ID는 특정 세션을 구분하기 위해 서버가 생성한 임의의 문자열이다.
세션 ID: q8fN2mK4xP...
브라우저에는 보통 세션 ID만 쿠키로 저장한다. 사용자 ID나 권한 같은 실제 로그인 정보는 서버의 메모리, 데이터베이스 또는 Redis 같은 별도의 세션 저장소에서 관리한다.
브라우저
sessionId=q8fN2mK4xP...
서버의 세션 저장소
q8fN2mK4xP... → userId: 15, role: USER, expiresAt: ...
따라서 세션 ID만 보고 사용자 정보를 직접 유추할 수 없어야 하며, 충분히 길고 예측하기 어려운 값으로 생성해야 한다.
사용자가 아이디와 비밀번호를 입력하면 다음 순서로 로그인이 진행된다.
1. 브라우저가 POST /login 요청을 보낸다.
2. 서버가 아이디와 비밀번호를 확인한다.
3. 인증에 성공하면 새로운 세션 ID를 생성한다.
4. 서버는 세션 ID와 사용자 정보를 세션 저장소에 연결한다.
5. Set-Cookie 응답 헤더로 세션 ID를 브라우저에 전달한다.
6. 브라우저는 이후 요청마다 세션 쿠키를 자동으로 전송한다.
7. 서버는 세션 저장소를 조회해 로그인 상태와 사용자를 확인한다.
서버의 응답은 다음과 같은 형태다.
Set-Cookie: sessionId=q8fN2mK4xP; HttpOnly; Secure; SameSite=Lax; Path=/
이후 브라우저는 조건에 맞는 요청마다 쿠키를 자동으로 포함한다.
Cookie: sessionId=q8fN2mK4xP
서버는 전달받은 세션 ID로 세션 저장소를 조회한다.
세션이 존재하고 만료되지 않음
→ 로그인 사용자로 처리
세션이 없거나 만료됨
→ 로그인하지 않은 사용자로 처리
이 과정 덕분에 사용자는 페이지를 이동하거나 API를 여러 번 호출해도 로그인 상태를 유지할 수 있다.
세션 기반 인증에서는 실제 사용자 정보와 권한을 서버가 관리한다. 사용자를 강제로 로그아웃시키거나 권한을 변경해야 할 때 서버의 세션을 삭제하거나 수정하면 바로 반영할 수 있다.
브라우저에는 의미 없는 세션 ID만 저장하므로 사용자 정보를 쿠키에 직접 넣는 방식보다 관리하기도 쉽다.
세션 방식은 서버가 로그인 상태를 저장해야 한다.
사용자가 많아지면 세션 데이터도 함께 증가한다. 세션을 애플리케이션 서버의 메모리에만 저장하면 서버 재시작 시 데이터가 사라질 수 있고, 서버를 여러 대 사용할 때 다른 서버에서는 해당 세션을 찾지 못하는 문제도 생긴다.
그래서 규모가 커지면 Redis나 데이터베이스처럼 여러 서버가 함께 접근할 수 있는 세션 저장소를 사용한다. 다만 이 경우 요청마다 저장소를 조회해야 하므로 네트워크 통신과 읽기·쓰기 비용이 추가된다.
세션 객체를 JSON으로 변환해 MySQL의 VARCHAR나 TEXT 등에 저장하는 구현이라면 직렬화와 역직렬화 비용도 발생한다.
세션 객체
→ JSON 문자열로 직렬화
→ 데이터베이스 저장
→ 데이터베이스 조회
→ 다시 객체로 역직렬화
세션에는 꼭 필요한 정보만 저장하고, 만료된 세션을 주기적으로 삭제하는 것이 좋다.
세션 ID가 탈취되면 공격자가 해당 사용자로 로그인할 수 있으므로 일반 쿠키보다 더 주의해서 관리해야 한다.
HttpOnly를 설정한다.Secure를 사용한다.SameSite=Lax 또는 Strict를 적용해 불필요한 교차 사이트 전송을 제한한다.특히 로그인 성공 시 세션 ID를 새로 발급하는 과정은 세션 고정 공격을 막기 위해 중요하다.
세션 기반 인증은 서버가 로그인 상태를 직접 관리하는 방식이다.
브라우저는 세션 ID를 보관하고
서버는 세션 ID에 연결된 사용자 정보를 보관한다.
브라우저가 요청마다 세션 쿠키를 보내면 서버가 이를 조회해 사용자를 확인한다. 구현 방식이 직관적이고 서버에서 세션을 통제하기 쉽지만, 사용자가 많아질수록 저장 공간과 세션 저장소 조회 비용이 증가한다.
참고 자료: MDN HTTP 개요, MDN 세션 관리, OWASP 세션 관리 가이드