쿠키(Cookies)와 세션(Session)
Series: 인증과 인가
들어가며
인증과 인가를 공부하다 보면 가장 먼저 마주치는 개념이 바로 쿠키(Cookies)와 세션(Session)이다. 특히 세션 기반 인증을 이해하려면 이 두 개념을 정확하게 구분하는 것이 중요하다. 처음에는 둘 다 "로그인을 유지하는 기술"처럼 보이기 때문에 헷갈리기 쉽다. 하지만 실제로는 역할이 완전히 다르다. 간단히 말하면, 쿠키는 "클라이언트에 저장되는 데이터"이고, 세션은 "서버가 로그인 상태를 관리하는 방식"이라고 할 수 있다. 이 글에서는 인증 흐름 속에서 쿠키와 세션이 각각 어떤 역할을 하는지 중심으로 정리해보겠다.
1. 왜 쿠키와 세션이 필요한가
HTTP는 기본적으로 상태를 기억하지 않는(stateless) 프로토콜이다. 즉, 서버는 이전 요청에서 사용자가 로그인했는지 여부를 자동으로 기억하지 못한다.
예를 들어 다음과 같은 상황을 생각해보자.
- 사용자가 로그인 요청을 보낸다 → 로그인 성공
- 이후 게시글 조회 요청을 보낸다
이때 서버는 두 번째 요청만 보고는 이 사용자가 로그인한 사용자라는 사실을 알 수 없다. 그래서 우리는 "로그인 상태를 유지하기 위한 방법"이 필요하다. 여기서 등장하는 것이 바로 세션이고, 그 세션을 요청마다 전달하기 위한 수단이 쿠키이다.
2. 세션: 로그인 상태를 서버가 기억하는 방식
세션은 서버가 사용자 상태를 직접 저장하는 방식이다. 사용자가 로그인에 성공하면 서버는 다음과 같은 정보를 어딘가에 저장한다.
{
"user_id": 1,
"logined_at": "2021-03-15 19:00:00",
"role": "user"
}이 정보를 저장한 뒤, 서버는 이 세션을 식별하기 위한 값인 session_id를 생성한다. 이 session_id는 일종의 "사용자 식별 키"이다. 서버는 이 값을 통해 어떤 사용자인지를 다시 찾아낼 수 있다. 중요한 점은, 실제 사용자 정보는 서버에 저장되고, 클라이언트는 이 정보를 직접 가지고 있지 않다는 것이다.
3. 쿠키: 세션을 전달하는 수단
세션만으로는 로그인 상태를 유지할 수 없다. 문제는 클라이언트가 매 요청마다 어떤 세션을 사용해야 하는지를 서버에게 알려줘야 한다는 점이다. 이 역할을 하는 것이 쿠키이다. 서버는 로그인 성공 시 다음과 같은 응답을 보낸다.
Set-Cookie: session_id=abc123브라우저는 이 값을 저장한다. 그리고 이후 같은 서버로 요청을 보낼 때마다 자동으로 이 쿠키를 포함시킨다.
Cookie: session_id=abc123서버는 이 값을 받아서 세션 저장소를 조회한다. 즉, 쿠키는 단순히 session_id를 전달하는 역할을 한다.
4. 전체 동작 흐름
쿠키와 세션이 함께 동작하는 과정을 하나로 정리하면 다음과 같다.
sequenceDiagram
participant Client as 클라이언트
participant Server as 서버
participant SessionStore as 세션 저장소
Client->>Server: 로그인 요청
Server->>SessionStore: 사용자 정보 저장
Server-->>Client: Set-Cookie(session_id)
Client->>Server: 요청 (Cookie 포함)
Server->>SessionStore: session_id 조회
SessionStore-->>Server: user_id 반환
Server-->>Client: 응답이 흐름에서 핵심은 다음이다.
- 클라이언트는
session_id만 가지고 있다 - 실제 사용자 정보는 서버가 가지고 있다
- 쿠키는 session_id를 전달하는 역할만 한다
5. 헷갈리기 쉬운 포인트
5.1. 쿠키 = 인증 방식이 아니다
많이 헷갈리는 부분 중 하나가 "쿠키로 인증한다"는 표현이다. 정확히 말하면 쿠키는 단순히 데이터를 전달하는 방법일 뿐, 인증 방식이 아니다.
예를 들어:
- 쿠키 +
session_id→ 세션 기반 인증 - 쿠키 +
JWT→ 토큰 기반 인증
즉, 인증 방식은 쿠키가 아니라 쿠키 안에 무엇을 담느냐에 의해 결정된다.
5.2. 세션은 서버에 있다
또 하나 중요한 포인트는, 세션은 클라이언트에 있는 것이 아니라 서버에 있다는 점이다. 클라이언트가 가지고 있는 것은 세션 자체가 아니라, 그 세션을 찾기 위한 '키(session_id)'뿐이다. 이 구조 때문에 서버는 언제든지 세션을 삭제하거나 만료시킬 수 있다.
예를 들어, 로그아웃을 하면 서버는 해당 세션을 삭제한다. 하지만, 클라이언트는 서버가 세션 정보를 삭제했다는 사실을 모르기때문에 여전히 session_id를 보낸다. 이 상황에서도 인증은 실패한다. 왜냐하면 서버에 세션이 없기 때문이다.
6. 인증 흐름에서의 역할 정리
인증 관점에서 보면 쿠키와 세션의 역할은 명확하게 나뉜다. 세션은 서버가 로그인 상태를 유지하기 위한 방식이고, 쿠키는 그 세션을 서버에 전달하기 위한 수단이다. 즉, 둘을 합쳐야 비로소 "로그인 유지"가 완성된다. 이 구조를 이해하면 이후에 배우게 될 개념들도 훨씬 자연스럽게 이어진다.
- 세션 기반 인증 → 서버가 상태 관리
- JWT 기반 인증 → 클라이언트가 상태 보관
마치며
쿠키와 세션은 항상 함께 등장하기 때문에 하나의 개념처럼 보이지만, 실제로는 역할이 명확하게 구분된다. 쿠키는 클라이언트에 저장되어 요청마다 자동으로 전송되는 데이터이고, 세션은 서버가 사용자 상태를 관리하는 방식이다. 인증 흐름에서 보면 쿠키는 "세션을 전달하는 수단"이고, 세션은 "로그인 상태를 유지하는 핵심 메커니즘"이다. 이 구조를 정확히 이해하면 세션 기반 인증뿐 아니라 JWT 기반 인증까지 훨씬 쉽게 이해할 수 있다. 결국 중요한 것은 "어디에 상태를 저장할 것인가"와 "그 상태를 어떻게 전달할 것인가"라는 두 가지를 구분해서 보는 것이라고 생각한다.