본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Frontend

쿠키와 세션

작성 2026. 10. 20.추가
목차9개 항목
출처와 참고

TIL을 정리하고, 서드파티 쿠키 부분은 web.dev의 「Learn Privacy」 강좌와 Privacy Sandbox 공식 발표로 보강했다. 쿠키와 세션 비교표는 ByteByteGo의 System Design 101 가이드 「What are the differences between cookies and sessions?」, 「What is a cookie?」를 바탕으로 보탰다.

HTTP는 요청 하나하나가 독립적인 무상태(stateless) 프로토콜이라, 그대로는 "방금 로그인한 그 사용자"를 기억하지 못한다. 쿠키(Cookie) 는 서버가 브라우저에 보내 저장시키는 작은 데이터 조각으로, 이후 같은 서버에 요청할 때마다 함께 전송되어 상태를 유지하게 해 준다. 세션(Session) 은 쿠키를 이용해 상태를 서버 쪽에 보관하는 방식이다.

쿠키의 동작

  1. 서버가 응답 헤더(Set-Cookie)로 쿠키를 보낸다.
  2. 브라우저는 쿠키를 key-value 형태로 로컬에 저장한다.
  3. 같은 서버에 다시 요청할 때 브라우저가 저장된 쿠키를 자동으로 함께 보낸다(Cookie 헤더).

쿠키로 사용자를 추적할 수 있고, 쿠키를 탈취당하면 계정 권한을 빼앗길 수도 있어 보안에 주의해야 한다.

사용 목적

목적예
세션 관리로그인 유지, 아이디 자동 완성, "오늘 하루 보지 않기" 팝업, 장바구니
개인화사용자 선호, 테마 설정
트래킹사용자 행동 기록·분석

쿠키의 수명

종류삭제 시점
세션 쿠키(Session cookie)현재 세션이 끝나면 삭제. 종료 시점은 브라우저가 정한다(세션 복원 기능이 있으면 더 오래 남기도 함)
영속 쿠키(Persistent cookie)Expires 속성의 날짜 또는 Max-Age 속성의 기간이 지나면 삭제

쿠키 속성

Set-Cookie: sid=abc; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=3600처럼 속성을 붙여 범위와 보안을 정한다.

속성역할
Domain·Path어느 도메인·경로로 가는 요청에 실을지. Domain을 생략하면 쿠키를 만든 호스트에만 간다
SecureHTTPS 요청에만 싣는다
HttpOnlyJavaScript(document.cookie)로 읽지 못하게 한다. 세션 쿠키에는 필수다
SameSite다른 사이트에서 시작된 요청에 실을지. Strict(안 실음), Lax(최상위 GET 이동에만 실음), None(항상 실음, Secure 필수). 값을 생략하면 크롬·엣지는 Lax로 다룬다
Partitioned서드파티 쿠키를 최상위 사이트별로 따로 저장한다(CHIPS). 임베드된 위젯이 사이트를 넘나들며 추적하지 못하게 한다. Secure가 필수다

JavaScript로 쿠키 다루기

HttpOnly가 없는 쿠키는 document.cookie로 읽고 쓸 수 있다. 인터페이스가 특이하다.

동작방법주의
읽기document.cookiename=value; name2=value2 한 문자열이다. 직접 나눠 파싱한다
쓰기document.cookie = "user=" + encodeURIComponent(v) + "; path=/; max-age=3600"대입 한 번에 쿠키 하나만 바뀐다. 다른 쿠키는 지워지지 않는다
지우기같은 이름·path·domain으로 max-age=0path나 domain이 다르면 다른 쿠키로 취급돼 지워지지 않는다

이름과 값은 encodeURIComponent로 인코딩한다. 쿠키 하나는 약 4KB, 도메인당 개수도 제한이 있다. 비동기로 쿠키를 읽고 쓰며 변경 이벤트까지 받는 Cookie Store API(cookieStore.get()·set(), change 이벤트)가 2025년에 Baseline이 됐다.

퍼스트파티와 서드파티 쿠키

주소창의 사이트가 직접 심은 쿠키가 퍼스트파티, 페이지에 들어 있는 다른 도메인(광고, 임베드)이 심은 쿠키가 서드파티다. 같은 도메인의 쿠키라도 어느 페이지 맥락에서 실리느냐에 따라 퍼스트파티도, 서드파티도 된다.

브라우저서드파티 쿠키 기본 동작
사파리예외 없이 차단(ITP)
파이어폭스최상위 사이트별로 분할(Total Cookie Protection)
크롬단계적 폐지를 철회하고 일반 창은 사용자 설정에 맡긴다(기본 허용). 시크릿 창은 차단

브라우저마다 다르므로 로그인·결제 흐름은 서드파티 쿠키에 기대지 않게 설계한다. 임베드 안의 상태는 Partitioned(CHIPS)로, 분할되지 않은 쿠키가 꼭 필요하면 Storage Access API로 처리한다. 브라우저별 세부 규칙과 크롬의 Privacy Sandbox 정리는 서드파티 쿠키와 브라우저 추적 방지에 있다.

쿠키와 Web Storage 비교

항목쿠키localStoragesessionStorage
만드는 쪽서버(Set-Cookie) 또는 JSJSJS
수명Expires·Max-Age, 없으면 브라우저 세션 동안지울 때까지탭을 닫을 때까지
요청마다 자동 전송OXX
범위도메인·경로출처(origin)출처 + 탭
용량쿠키당 약 4KB출처당 약 5MiB출처당 약 5MiB
JS 접근HttpOnly면 불가가능가능
  • 셋 다 문자열만 저장한다. 구조화된 큰 데이터는 IndexedDB를 쓴다.
  • 탭을 복제하면 sessionStorage도 복사된다.
  • 실제로 저장된 값은 DevTools Application 패널에서 보고 고칠 수 있다(DevTools Application 패널).

세션

세션 방식은 민감한 정보를 쿠키에 직접 담지 않는다. 서버가 세션 데이터를 저장하고, 브라우저에는 그 데이터를 찾을 세션 ID만 쿠키로 준다. 로그인부터 조회까지의 흐름은 세션 기반 인증과 토큰 기반 인증에 있다.

구분쿠키에 값을 직접 담기세션
데이터 위치사용자 기기서버(메모리·Redis·DB). 쿠키에는 세션 ID만
크기쿠키당 약 4KB서버 저장소가 허락하는 만큼
서버 조회필요 없다. 요청에 이미 실려 온다요청마다 세션 ID로 저장소를 조회한다
변조·노출사용자가 읽고 고칠 수 있다. 쓰려면 서명·암호화가 필요하다사용자는 ID만 본다
사용자 통제브라우저에서 쿠키를 막거나 지울 수 있다쿠키가 막히면 세션 ID도 전달되지 않는다

쿠키에 값을 직접 담는 방식은 언어 설정·테마처럼 노출돼도 괜찮고 서버가 매번 DB를 보지 않아도 되는 선호값에 맞다. 로그인 상태나 권한처럼 신뢰해야 하는 값은 세션(또는 서명된 토큰)으로 둔다.

로그아웃할 때는 서버의 세션을 지우고, 응답에 Clear-Site-Data: "cookies", "storage"를 붙여 브라우저에 남은 쿠키·저장소까지 지운다(데이터 최소화와 프라이버시 실천).

세션 저장소 확장(Redis), 세션 고정 공격, 토큰(JWT) 방식과의 비교도 같은 노트에 있다.

Django는 SessionMiddleware로 세션을 처리하고 세션 데이터를 DB에 둔다 → Django User와 인증.

핵심 정리

  • 쿠키 = 서버가 브라우저에 저장시키고, 브라우저가 매 요청에 자동으로 실어 보내는 작은 데이터.
  • 세션 = 상태는 서버에, 식별자(세션 ID)만 쿠키에 두는 방식.
  • 쿠키가 "자동으로 전송된다"는 성질 때문에 CSRF 같은 공격이 가능해진다. HttpOnly·Secure·SameSite로 범위를 좁힌다.

관련 노트: HTTP 프로토콜, 서드파티 쿠키와 브라우저 추적 방지, Django User와 인증, NestJS JWT 인증(토큰 방식), SWR로 서버 데이터 가져오기(로그인 상태 판단), OAuth 2.0, DevTools Application 패널: 저장소·서비스 워커, DevTools Network 패널

원본 기록7

댓글

GitHub 계정으로 댓글을 남길 수 있어요.