BioPlayground

🧬
목록으로

쿠키란 무엇인가 — HTTP 상태 관리

HTTP 쿠키가 왜 필요한지, 어떻게 작동하는지, 보안 속성은 무엇인지 Express 예시로 배웁니다.

중급
|
10
|
검증 완료 (2026-07)
쿠키HTTP 상태 관리Set-Cookie세션인증
진행률0/20 (0%)

쿠키란 무엇인가 — HTTP 상태 관리

이 토픽을 마치면

HTTP가 왜 "상태 없는" 프로토콜인지 이해하고, 쿠키가 이 문제를 어떻게 해결하는지 설명할 수 있으며, Express에서 쿠키를 설정하고 읽는 방법을 알게 됩니다.


HTTP는 기억력이 없다

HTTP 프로토콜은 무상태(stateless) 입니다. 서버는 요청을 하나 처리하고 나면 클라이언트를 완전히 잊어버립니다.

text
Client: GET /page1 → Server: "Page 1 내용이요"
Client: GET /page2 → Server: "누구세요? 처음 뵙겠습니다. Page 2 내용이요"

브라우저가 1초 전에 /page1을 요청했던 같은 사용자인지, 서버는 알 수 없습니다. 로그인도, 장바구니도, 다크모드 설정도 — "이전 요청을 기억"해야 하는 모든 기능이 이 무상태 특성 때문에 불가능합니다.

쿠키는 이 문제를 해결합니다. 서버가 클라이언트에게 "이 정보를 저장해두고, 다음에 올 때 보여줘"라고 하는 것입니다.


쿠키의 작동 원리

쿠키는 HTTP 헤더를 통해 주고받습니다.

text
1. 서버 → 클라이언트 (응답 헤더)
   Set-Cookie: username=Hoon; Path=/

2. 클라이언트 → 서버 (다음 요청의 요청 헤더)
   Cookie: username=Hoon

한 번 설정하면, 브라우저는 같은 도메인의 모든 요청에 쿠키를 자동으로 포함합니다. 서버가 시키지 않아도 브라우저가 알아서 보내줍니다. 이것이 쿠키의 핵심 메커니즘입니다.


Express에서 쿠키 다루기

쿠키 설정

javascript
const express = require('express');
const app = express();

app.get('/login', (req, res) => {
  // Set-Cookie 헤더를 보냄
  res.cookie('username', 'Hoon', {
    maxAge: 24 * 60 * 60 * 1000, // 1 day (milliseconds)
    httpOnly: true,
    secure: false,    // HTTPS에서만 전송 (개발 중 false)
    sameSite: 'lax'
  });
  res.json({ message: 'Logged in, cookie set' });
});

쿠키 읽기

쿠키를 읽으려면 cookie-parser 미들웨어가 필요합니다.

bash
npm install cookie-parser
javascript
const cookieParser = require('cookie-parser');
app.use(cookieParser());

app.get('/profile', (req, res) => {
  const username = req.cookies.username;
  if (!username) {
    return res.status(401).json({ error: 'Not logged in' });
  }
  res.json({ message: `Welcome back, ${username}` });
});

cookie-parserCookie 헤더를 파싱해서 req.cookies 객체로 만들어줍니다. 이 미들웨어 없이는 헤더를 직접 파싱해야 합니다.

쿠키 삭제

javascript
app.get('/logout', (req, res) => {
  res.clearCookie('username');
  res.json({ message: 'Logged out, cookie cleared' });
});

clearCookie는 같은 이름의 쿠키를 즉시 만료시킵니다.


쿠키의 속성들

속성설명예시
maxAge수명 (밀리초). 이 시간이 지나면 자동 삭제86400000 (1일)
expires만료 일시 (Date 객체). maxAge보다 덜 쓰임new Date('2026-12-31')
httpOnlyJavaScript에서 접근 불가 (XSS 방어 핵심)true
secureHTTPS 연결에서만 전송true
sameSite다른 사이트에서의 요청에 쿠키 포함 여부'strict', 'lax', 'none'
path이 경로 하위에서만 쿠키 전송'/'
domain쿠키가 유효한 도메인'.example.com'

이 속성들 중 httpOnlysecure가 보안에서 가장 중요합니다.


보안 — 쿠키를 안전하게

httpOnly

javascript
// Bad — JavaScript로 쿠키 접근 가능 (XSS 취약)
res.cookie('token', 'abc123');

// Good — JavaScript로 접근 불가
res.cookie('token', 'abc123', { httpOnly: true });

httpOnly: true를 설정하면 document.cookie로 읽을 수 없습니다. XSS 공격자가 스크립트를 주입해도 쿠키를 훔칠 수 없습니다. 인증 관련 쿠키에는 반드시 설정해야 합니다.

secure

javascript
res.cookie('token', 'abc123', { 
  httpOnly: true,
  secure: true  // HTTPS에서만 전송
});

HTTP(암호화 안 됨) 연결에서는 쿠키가 전송되지 않습니다. 중간자(MITM)가 쿠키를 가로챌 수 없습니다.

sameSite

javascript
res.cookie('token', 'abc123', {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'  // 같은 사이트 요청에서만 전송
});
동작
'strict'같은 사이트에서 온 요청만 쿠키 포함. CSRF 완전 차단. 단, 외부 링크로 진입 시 로그아웃 상태
'lax'GET 요청(링크 클릭)은 허용, POST는 차단. 대부분의 CSRF 방어 + 편의성 절충. 권장
'none'모든 요청에 포함. secure: true 필수. 크로스사이트 API에서만 사용

쿠키 vs 로컬 스토리지

쿠키localStorage
서버 전송자동으로 매 요청에 포함전송되지 않음
용량~4KB~5MB
만료자동 만료 가능수동 삭제만
접근httpOnly이면 JS 접근 불가JS로만 접근
용도인증, 세션, 서버 설정UI 상태, 캐시, 오프라인 데이터

"서버가 알아야 하는 정보"는 쿠키, "브라우저만 알면 되는 정보"는 localStorage입니다.


실전 패턴 — 다크모드 쿠키

javascript
// 다크모드 설정 — 서버에서 렌더링 시 적용 가능
app.post('/settings/theme', (req, res) => {
  const { theme } = req.body; // 'dark' or 'light'
  res.cookie('theme', theme, {
    maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year
    httpOnly: false,  // CSS 적용 위해 JS 접근 필요
    sameSite: 'lax'
  });
  res.json({ theme });
});

app.get('/', (req, res) => {
  const theme = req.cookies.theme || 'light';
  res.render('index', { theme });
});

다크모드처럼 보안에 민감하지 않은 설정은 httpOnly: false로 해도 됩니다. 하지만 인증 토큰은 절대 httpOnly: false로 설정하면 안 됩니다.


핵심 정리

개념한 줄 정리
HTTP 무상태서버는 이전 요청을 기억하지 않음
쿠키서버가 클라이언트에게 맡기는 작은 데이터 조각
Set-Cookie서버 → 클라이언트 (응답 헤더)
Cookie클라이언트 → 서버 (요청 헤더, 자동)
httpOnlyJS 접근 차단 (XSS 방어)
secureHTTPS에서만 전송
sameSiteCSRF 방어 (lax 권장)

쿠키는 웹의 가장 오래된 상태 관리 메커니즘이지만, 여전히 가장 널리 쓰입니다. 세션, 인증, 사용자 설정 — 이 모든 것의 기반이 쿠키입니다. 보안 속성(httpOnly, secure, sameSite)을 빠뜨리면 XSS와 CSRF에 노출되므로, 쿠키를 설정할 때는 항상 이 세 가지를 먼저 체크합니다.


실전 체크리스트

인증 쿠키를 설정할 때 반드시 확인해야 할 항목:

javascript
res.cookie('session_token', token, {
  httpOnly: true,       // ✓ XSS 방어 — JS에서 접근 불가
  secure: true,         // ✓ HTTPS 전용 — 평문 전송 차단
  sameSite: 'lax',      // ✓ CSRF 방어 — 크로스사이트 POST 차단
  maxAge: 3600000,      // ✓ 만료 설정 — 영구 쿠키 방지
  path: '/'             // ✓ 경로 제한 — 필요한 범위만
});

이 다섯 가지를 하나라도 빠뜨리면 보안 취약점이 됩니다. 프로덕션에 배포하기 전에 이 체크리스트를 반드시 확인합니다.