HTTP 프로토콜은 두 가지 핵심 특성을 가진다.
이로 인해 "로그인한 사용자가 페이지를 이동할 때 로그인 상태를 어떻게 유지할 것인가?"라는 문제가 발생한다. 매번 아이디/비밀번호를 요청에 실어 보낼 수는 없으므로, 이를 해결하기 위해 쿠키(Cookie)와 세션(Session) 개념이 도입되었다.
쿠키는 서버가 클라이언트(브라우저)에 저장하는 작은 데이터 조각(Key-Value 형태)이다.
[클라이언트] ---> (1) 로그인 요청 (ID/PW) ---> [서버]
[클라이언트] <--- (2) 응답 + Set-Cookie <--- [서버]
[클라이언트] ---> (3) 요청 + Cookie Header ---> [서버] (상태 유지)
Set-Cookie를 실어 보냄.Cookie 헤더에 담아 전송함.쿠키는 브라우저에 저장되므로 클라이언트 측에서 손쉽게 조회 및 변조가 가능하다. 이를 방지하기 위한 핵심 플래그 설정이 필수적이다.
HttpOnly: JavaScript(document.cookie)를 통한 쿠키 접근을 차단함. XSS(Cross-Site Scripting) 공격으로 인한 쿠키 탈취 방지.Secure: HTTPS 통신 환경에서만 쿠키를 전송하도록 제한함. 네트워크 스니핑 방지.SameSite: Cross-Site 요청 시 쿠키 전송 여부를 제어해 CSRF(Cross-Site Request Forgery) 공격을 방어함.Strict: 타 사이트에서 발생하는 모든 요청에 쿠키 미전송.Lax: 기본값. 링크 클릭 등 일부 Safe 요청에만 쿠키 전송.None: 모든 Cross-Site 요청에 쿠키 전송 (Secure 옵션 필수).쿠키에 민감한 정보(예: 사용자 ID, 권한 등)를 직접 담으면 보안상 매우 위험함. 따라서 민감한 정보는 서버 메모리나 DB에 저장하고, 클라이언트에게는 난수화된 '세션 ID'만 발급하는 방식이 세션 기반 인증임.
[클라이언트] ---> (1) 로그인 요청 ---> [서버] (인증 성공 후 Session DB에 저장)
[클라이언트] <--- (2) 응답 + Set-Cookie: <--- [서버] (JSESSIONID=a1b2c3d4...)
JSESSIONID
[클라이언트] ---> (3) 요청 + Cookie Header ---> [서버] (Session ID 조회 후 사용자 식별)
Session ID를 생성함.Set-Cookie를 통해 Session ID만 클라이언트에 전달함.Session ID가 담긴 쿠키를 전송하고, 서버는 세션 저장소에서 해당 ID를 조회해 사용자를 식별함.세션의 서버 저장소 부담을 줄이고 Stateless한 구조를 유지하기 위해 자주 사용되는 방식이다.
JWT는 .을 구분자로 세 부분으로 구성된 문자열이다.
Header.Payload.Signature
LocalStorage 또는 HttpOnly Cookie).Authorization: Bearer <JWT_TOKEN> 헤더에 담아 전송.| 구분 | 세션 (Session) | 토큰 (JWT) |
|---|---|---|
| 상태 저장 여부 | Stateful (서버에 상태 저장) | Stateless (서버에 상태 저장 안 함) |
| 정확한 제어 | 서버에서 즉시 세션 강제 종료/만료 가능 | 발급된 토큰은 만료 전까지 강제 정지 어려움 |
| 확장성 | 다중 서버 환경 시 Redis 등 추가 세션 서버 필요 | 서버 확장(Scale-Out) 시 별도 저장소 없이 검증 가능 |
| 데이터 크기 | 쿠키에 ID만 들어가므로 작음 | Payload 정보에 따라 토큰 크기가 커질 수 있음 |
HttpOnly, Secure, SameSite=Lax/Strict 옵션 적용.