HTTP 쿠키 이해하기

쿠키(Cookie) 완전 정복: 개발자가 알아야 할 모든 것

쿠키는 웹 개발에서 클라이언트를 식별하고 상태를 유지하는 핵심 기술이다.
이번 글에서는 쿠키의 기초부터 실무에서 자주 쓰이는 옵션, 보안 설정, 그리고 서버·브라우저 라이브러리 활용법까지 차근차근 살펴본다.


1. 쿠키의 시작: 매직 쿠키와 무상태 HTTP

매직 쿠키란?

유닉스 환경에서 받은 쿠키를 그대로 돌려보내는 것을 매직 쿠키(Magic Cookie)라고 부른다.
30년 전 쇼핑카트 구현 아이디어로 사용되었고, 오늘날의 웹 쿠키의 시초가 되었다.

첫 사용 사례는 사이트 재방문 확인이었다.
방문자의 브라우저에 값을 저장해 두었다가, 다음 접속 시 서버가 이를 보고 “아, 이 사람은 전에 왔던 사람!” 하고 알아보는 방식이다.

마치 단골 카페에서 커피를 주문할 때, 주인이 “어제 드신 아메리카노 다시 드릴까요?”라고 묻는 것과 같다. 서버가 나를 기억하게 만드는 것이다.


2. HTTP는 왜 ‘무상태’인가?

HTTP는 Stateless Protocol이다.
즉, 각 요청과 응답은 서로 독립적으로 처리되며, 서버는 이전 요청의 정보를 기억하지 않는다.

이 특성 덕분에 확장성은 뛰어나다.
예를 들어, 서버를 여러 대로 확장해도 어느 서버든 모든 요청을 처리할 수 있다.
서버가 클라이언트를 ‘기억’하지 않아도 되기 때문이다.

하지만 웹 애플리케이션 개발자 입장에서는 곤란한 경우가 많다.
로그인 상태 유지, 장바구니 저장, 방문자 맞춤 페이지 등은 사용자의 상태를 추적해야 하기 때문이다.


쿠키로 상태를 부여하기

이 문제를 해결하기 위해 서버는 응답 헤더에 Set-Cookie를 내려보낸다.
브라우저는 이 값을 저장한 뒤, 같은 도메인에 다시 요청할 때 Cookie 헤더에 실어 보낸다.

< Set-Cookie: sid=1   # 서버 → 브라우저: 세션 식별자 전달
> Cookie: sid=1       # 브라우저 → 서버: 저장된 쿠키 반환http

서버는 sid 값을 보고 “이 사용자는 이전에 왔던 사람”이라고 판단할 수 있게 된다.


쿠키를 심어보는 실습

아래 Node.js 예제는 첫 방문 시와 재방문 시의 응답을 다르게 처리한다.

const http = require('http');

const handler = (req, res) => {
  const cookie = req.headers['cookie'];

  if (cookie && cookie.includes('sid')) {
    res.write('Hello Again.\n');
    res.end();
    return;
  }

  res.setHeader('Set-Cookie', 'sid=1');
  res.write('Hello.\n');
  res.end();
};

http.createServer(handler).listen(3000, () => {
  console.log('server is running');
});js
  • 첫 방문 → Hello.
  • 두 번째 방문 → Hello Again.

이렇게 Set-CookieCookie 헤더를 주고받으면, 원래 무상태인 HTTP에 상태를 부여할 수 있다.


3. 쿠키의 유효 범위: Domain & Path

쿠키는 도메인과 경로를 기준으로 전송 범위가 결정된다.
쉽게 말해, 브라우저가 한 번 받은 쿠키를 모든 HTTP 요청에 무작정 담아 보내는 건 아니다.
기본적으로 같은 도메인으로 요청할 때만 해당 쿠키를 전송한다.

이 말은 곧, 브라우저가 쿠키와 함께 쿠키가 속한 도메인 정보까지 기억한다는 뜻이다.


로컬 환경에서 도메인 테스트하기

로컬 개발 환경이라고 해서 항상 localhost만 사용할 필요는 없다.
테스트를 위해 다른 도메인을 직접 매핑해볼 수도 있다.

예를 들어, macOS에서는 /etc/hosts 파일을 수정해 로컬 주소에 원하는 도메인을 매핑할 수 있다.

sudo vi /private/etc/hostsbash

i를 눌러 편집 모드로 들어간 뒤, 아래와 같이 추가한다.

127.0.0.1 yolog.co.kr
127.0.0.1 login.yolog.co.krbash

호스트를 바꾸는 방법
호스트를 바꾸는 방법

이제 yolog.co.krlogin.yolog.co.kr 모두 로컬 서버(127.0.0.1)로 접근할 수 있다.


서로 다른 서브도메인에서의 쿠키 전송

예를 들어, yolog.co.kr에서 발급받은 쿠키는 login.yolog.co.kr로 요청을 보낼 때 자동으로 전송되지 않는다.
브라우저는 쿠키의 Domain 속성을 엄격하게 따르며, 지정된 도메인 외부로는 쿠키를 보내지 않기 때문이다.

이 덕분에 민감한 식별 정보가 불필요하게 다른 도메인으로 전송되는 일을 방지할 수 있다.
하지만 경우에 따라서는 다른 서브도메인에서도 동일한 쿠키를 공유해야 할 때가 있다.


Domain 디렉티브

대표적인 사례는 로그인 인증이다.
예를 들어, 사용자가 login.yolog.co.kr에서 로그인하면, 메인 도메인 yolog.co.kr에서도 인증 상태를 유지하고 싶을 수 있다.

이럴 때는 서버에서 쿠키를 발급할 때 Domain 속성을 메인 도메인으로 지정하면 된다.

res.setHeader('Set-Cookie', 'sid=1; Domain=yolog.co.kr');js

이렇게 하면 yolog.co.kr뿐 아니라 login.yolog.co.kr에서도 같은 쿠키를 전송할 수 있게 된다.

Path 디렉티브

경로 단위로 쿠키 전송 범위를 제한한다.

res.setHeader('Set-Cookie', 'sid=1; Path=/private');js
  • /private 요청 시 → 쿠키 전송
  • /public 요청 시 → 쿠키 없음

참고 자료: MDN - 쿠키의 Domain과 Path


4. 쿠키의 생명주기: 세션 쿠키 vs 영속 쿠키

기본적으로 브라우저는 종료 시 세션 쿠키를 삭제한다.
하지만 로그인 유지 같은 경우에는 영속 쿠키(Permanent Cookie)가 필요하다.

  • Max-Age: 쿠키 수명을 초 단위로 설정
  • Expires: 특정 만료일 설정
res.setHeader('Set-Cookie', 'sid=1; Max-Age=10'); // 10초 후 만료js

실제로 이렇게 쿠키를 변경하고, 10초 후에 다시 요청을 보내면 쿠키가 삭제되는 것을 확인할 수 있다.

  • Hello → Hello (10초 후 요청시)
  • Hello → Hello Again. (10초 이내 요청시)

마치 영화관 티켓에 상영 시간이 적혀있는 것과 같다. 시간이 지나면 티켓은 무효가 되는 것이다.


5. 보안 속성: Secure & HttpOnly

Secure

HTTPS 요청에서만 쿠키 전송한다.

res.setHeader('Set-Cookie', 'sid=1; Secure');js

참고 자료: MDN - Secure 쿠키

HttpOnly

JavaScript에서 document.cookie 접근을 차단한다.
XSS 공격 방어에 필수다.

res.setHeader('Set-Cookie', 'sid=1; HttpOnly');js

마치 은행 금고에 중요한 서류를 보관하는 것과 같다. 아무나 접근할 수 없게 만드는 것이다.

참고 자료: MDN - HttpOnly 쿠키


6. 서버에서 쿠키 다루기

Express는 res.cookie(name, value, options)로 쿠키를 쉽게 설정할 수 있다.
문자열 직렬화는 cookie 라이브러리, 파싱은 cookie-parser 미들웨어가 담당한다.

res.cookie('sid', '1', { httpOnly: true });
console.log(req.cookies.sid); // "1"js

7. 브라우저에서 쿠키 다루기

HttpOnly가 없는 쿠키는 JS로도 제어할 수 있다.
팝업 “오늘 하루 보지 않기” 기능처럼 클라이언트 상태 저장에 유용하다.

// 설정 (1일 보관)
Cookies.set('checked', 'true', { expires: 1 });

// 조회
Cookies.get('checked'); // "true"

// 삭제
Cookies.remove('checked');js

8. 마무리

쿠키는 단순히 “브라우저 저장소”가 아니라 HTTP와 밀접한 상태 관리 기술이다.
도메인·경로·생명주기·보안 옵션을 이해하면, 로그인, 세션 관리, 사용자 경험 개선까지 모두 손에 넣을 수 있다.

핵심 정리

  • 쿠키의 역할: HTTP의 무상태 특성을 보완하여 사용자 상태를 추적
  • Domain & Path: 쿠키 전송 범위를 제한하여 보안 강화
  • 생명주기: Max-Age와 Expires로 세션 쿠키와 영속 쿠키 구분
  • 보안 속성:
    • Secure: HTTPS에서만 전송
    • HttpOnly: JavaScript 접근 차단으로 XSS 방어
    • SameSite: CSRF 공격 방어
  • 실무 팁: 쿠키를 세션 저장소와 연계하거나, JWT 등과 조합해 사용

보안 속성(Secure, HttpOnly)은 세션 하이재킹XSS 공격을 방어하기 위해 반드시 사용하는 것을 추천한다.