HTTP의 Stateless 한계를 극복한 세 가지 기술 | Cookie · Session · Token 완전 정리

2025. 10. 29. 11:29CS정리

HTTP의 Stateless 한계를 극복한 세 가지 기술 | Cookie · Session · Token 완전 정리


❶ HTTP는 왜 상태를 기억하지 못할까?

HTTP(HyperText Transfer Protocol)은 요청(Request)과 응답(Response)만으로 이루어진 단순한 프로토콜이다. 즉, 서버는 클라이언트가 누군지 기억하지 못한다. 이 때문에 “기억력 없음(Stateless)”이라는 특징을 가진다.

하지만 사용자가 로그인한 상태로 페이지를 이동하거나 장바구니를 유지하려면 서버가 사용자의 상태를 **어느 정도 기억할 필요가 있다.** 이를 해결하기 위해 등장한 것이 바로 Cookie, Session, Token 세 가지 방식이다.

---

❷ Cookie — 클라이언트 측 저장 방식

쿠키는 서버가 클라이언트(브라우저)에 작은 데이터 파일을 저장시켜 두는 방식이다. 같은 도메인으로 요청할 때 브라우저는 이 쿠키를 자동으로 전송하여, 서버가 사용자를 식별할 수 있게 한다.

작동 방식

  1. 클라이언트가 로그인 요청
  2. 서버가 Set-Cookie 헤더를 통해 쿠키 전달
  3. 클라이언트(브라우저)가 쿠키를 저장
  4. 이후 같은 서버에 요청 시 Cookie 헤더에 자동 포함
Set-Cookie: userId=jinwoo; Path=/; HttpOnly;
Cookie: userId=jinwoo

특징

  • 브라우저 내부에 저장됨 (사용자 PC 로컬 파일로 존재)
  • key-value 형태의 문자열
  • 사용자가 직접 삭제 가능
  • 용량 제한 약 4KB
  • 보안이 약해 민감한 정보 저장에 부적합

➡️ 정리: 클라이언트가 기억하는 데이터. 단순하지만 조작 위험이 존재함.

---

❸ Session — 서버 측 저장 방식

세션은 서버가 사용자의 상태를 직접 기억하는 방식이다. 즉, 서버가 클라이언트별로 고유한 Session ID를 발급하고, 이 값을 쿠키에 담아 클라이언트에 저장한다.

작동 방식

  1. 사용자 로그인 → 서버가 세션 데이터(user_id, 로그인시간 등) 생성
  2. 서버는 세션 ID를 만들고, Set-Cookie로 전달
  3. 클라이언트가 이후 요청 시 쿠키에 담긴 세션 ID를 함께 전송
  4. 서버는 세션 ID를 통해 해당 데이터를 찾아 인증
Set-Cookie: JSESSIONID=abc123xyz; Path=/; HttpOnly;
Cookie: JSESSIONID=abc123xyz

특징

  • 서버가 상태를 저장 → Stateful 구조
  • 로그인 유지, 장바구니, 결제 등 사용자별 상태 관리에 적합
  • 서버에 저장 공간 필요 (사용자 많을수록 부하 증가)
  • 서버 확장 시 세션 동기화 문제 발생 → Redis 등 별도 저장소 사용

➡️ 정리: 세션은 서버가 기억하고, 쿠키는 세션 ID만 전달하는 역할.

---

❹ Token — 완전한 Stateless 인증 방식 (JWT 등)

토큰 방식은 “서버가 사용자를 기억하지 않아도” 클라이언트가 자신의 신분증(Token)을 들고 다니는 구조다. 대표적으로 JWT (JSON Web Token)이 많이 쓰인다.

작동 방식

  1. 사용자 로그인 성공 → 서버가 사용자 정보를 암호화한 JWT 발급
  2. 클라이언트가 토큰을 localStorage, sessionStorage 또는 쿠키에 저장
  3. 요청 시 Authorization: Bearer <token> 형태로 헤더에 포함
  4. 서버는 토큰을 복호화해 사용자 정보와 만료 시간 검증
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

📄 특징

  • 서버에 사용자 상태 저장 X → 완전한 Stateless
  • 분산 서버, 마이크로서비스 환경에 적합
  • 세션 공유 문제 없음 → 서버 확장성 높음
  • 토큰 탈취 시 만료 전까지 유효 → 보안 관리 필요
  • Access Token / Refresh Token 갱신 로직 필수

---

❺ JWT의 구조

JWT는 3부분으로 구성되어 있다:

Header.Payload.Signature
(예: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJqaW53b28ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)
구성 요소 설명
Header 토큰 타입(JWT)과 서명 알고리즘(HS256 등) 명시
Payload 사용자 ID, 권한, 만료 시간 등 실제 데이터
Signature 서버의 비밀키로 Header + Payload를 암호화한 서명 부분

서버는 토큰을 복호화하지 않고도 서명을 검증하여 위조 여부를 판단할 수 있다.

---

❻ Access Token과 Refresh Token

JWT 기반 인증에서, 클라이언트는 두 가지 토큰을 사용한다: Access Token과 Refresh Token

1️⃣ Access Token

Access Token은 짧은 수명을 가진 토큰으로, 사용자가 인증을 받으면 서버가 발급한다. 이 토큰은 주로 Authorization 헤더에 담겨 API 서버에 전달된다.

Authorization: Bearer 

✅ 장점: - 빠르게 검증할 수 있는 작은 크기의 토큰 - 만료 시간이 짧아, 보안상 유리 (만료 후 재인증 필요)

❌ 단점: - 만료 후 재로그인이 필요함 - 길지 않기 때문에 토큰 크기 및 전송이 비교적 간단하다.

2️⃣ Refresh Token

Refresh Token은 Access Token의 만료 후, 새로운 Access Token을 발급받기 위해 사용된다. Refresh Token은 긴 수명을 가지며, 서버에서 직접 관리된다. 클라이언트는 만료된 Access Token을 갱신하기 위해 Refresh Token을 서버에 보내고, 서버는 이를 통해 새로운 Access Token을 발급한다.

POST /refreshToken
{
  "refreshToken": ""
}

장점: - 사용자가 매번 로그인할 필요 없이 토큰을 갱신 가능 - 보안적으로 서버가 관리하므로, 만료된 Access Token을 쉽게 갱신할 수 있다.

단점: - 만약 Refresh Token이 탈취되면, 새로운 Access Token을 발급받을 수 있어 보안 위협이 될 수 있음 - 토큰 관리가 복잡하고, 서버 부담이 있을 수 있다.

---

❼ Cookie · Session · Token 비교 정리

구분 저장 위치 서버 상태 저장 보안성 특징
Cookie 클라이언트(브라우저) 낮음 간단, 자동 전송, 조작 가능
Session 서버 중간~높음 서버 관리 필요, 로그인 유지
Token (JWT) 클라이언트(localStorage 등) 중간~높음 분산 환경 적합, 서버 부담 적음

---

❼ 핵심 요약

  • HTTP는 Stateless — 서버는 클라이언트의 상태를 기억하지 않는다.
  • Cookie → 클라이언트가 정보를 저장 (간단하지만 보안 약함)
  • Session → 서버가 상태를 저장 (안정적이지만 부하 있음)
  • Token (JWT) → 클라이언트가 암호화된 인증 정보를 소지 (Stateless 인증)
  • 현대의 REST API, 모바일, 마이크로서비스 환경에서는 대부분 JWT 기반 인증을 사용한다.

---

마무리

쿠키는 브라우저가 기억하고, 세션은 서버가 기억하며, 토큰은 사용자가 스스로 증명한다.

이 세 가지 기술은 HTTP의 Stateless 구조를 실용적으로 보완하며, 오늘날 대부분의 인증 시스템의 근간이 되고 있다.