개발 학습 실습실

이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.

기초개념 › 네트워크

쿠키

쿠키는 무엇이고, 누가 저장하고 누가 보내는가

HTTP에서는 요청 하나하나가 따로여서, 서버는 두 번째 요청이 아까 그 사람에게서 온 것인지 스스로는 알 수 없습니다. 쿠키는 이 문제를 풀기 위한 작은 값입니다. 코드 칸에는 서버가 첫 요청에 돌려주는 응답 글이 있고, 그 안의 Set-Cookie: visitor=kim 줄이 쿠키를 맡기는 줄입니다. 서버는 이 줄로 "이 값을 맡아 두었다가 다음에 올 때 보여 달라"고 부탁합니다. 값을 저장하는 것도, 다시 보내는 것도 브라우저입니다. 브라우저는 저장해 둔 값을 같은 서버로 가는 다음 요청에 Cookie: visitor=kim 헤더로 붙여 보냅니다. 이 실습의 서버는 요청에 Cookie 헤더로 visitor 값이 오면 "또 오셨군요, 값"을, 없으면 "처음 오셨군요"를 돌려주게 만들어 둔 서버이고, 그 서버 코드는 화면에 보이지 않습니다. Set-Cookie 줄을 지우거나, 둘째 요청 전에 쿠키를 지우거나, 쿠키를 저장하지 않는 프로그램으로 요청해 가며, 같은 서버에 두 번 요청했을 때 서버가 둘째 요청을 알아보는지를 봅니다. 코드 칸의 (빈 줄)은 아무 글자도 없는 줄을 눈에 보이게 적은 것입니다.

실행으로 대조 · Node.js 24.18.0의 net 서버와 curl 8.21.0의 쿠키 엔진으로 여섯 가지 조합을 실행해 대조(브라우저에서는 실행하지 않음)

이 실습에 나오는 개념

쿠키
서버가 응답에 실어 보내면 브라우저가 저장해 두었다가 같은 사이트에 요청할 때마다 자동으로 함께 보내는 작은 데이터다. HTTP는 요청 사이의 상태를 기억하지 않으므로, 로그인 상태처럼 이어져야 하는 정보를 유지하는 데 쓰인다. 사용자의 브라우저에 저장되므로 내용을 보거나 바꿀 수 있다는 점을 전제로 사용해야 한다.
Set-Cookie 헤더
Set-Cookie는 서버가 응답에 붙여 쿠키를 클라이언트(브라우저 같은 사용자 에이전트)에 보내는 응답 헤더이다(RFC 6265 4.1절). Set-Cookie: visitor=kim처럼 "이름=값" 하나로 시작하며, 뒤에 만료나 경로 같은 속성을 덧붙일 수 있다. 뜻은 "이 값을 맡아 두었다가 다음에 올 때 보여 달라"는 부탁이다. 값을 저장해 두었다가 같은 서버로 가는 요청에 돌려보낼지는 받은 쪽이 정하므로, 쿠키를 저장하지 않는 프로그램은 이 줄을 받아도 쓰지 않는다.
Cookie 헤더
Cookie는 클라이언트가 저장해 둔 쿠키를 서버로 돌려보낼 때 요청에 붙이는 헤더이다(RFC 6265 4.2절). Cookie: visitor=kim처럼 저장해 둔 "이름=값"만 적고, 만료나 경로 같은 속성은 싣지 않는다(4.2.1절). 브라우저가 쿠키를 보낼 조건에 맞는 요청에 이 헤더를 붙이므로, 개발자가 요청을 보내는 코드에 따로 쓰지 않는다. 서버는 이 헤더를 읽어 어떤 쿠키를 가진 클라이언트의 요청인지 알아볼 수 있고, 헤더를 무시할 수도 있다(3절).
HTTP와 무상태(Stateless)
HTTP는 클라이언트가 요청을 보내면 서버가 응답하는 방식의 통신 규약이다. 무상태라는 것은 서버가 이전 요청의 내용을 기억하지 않아 각 요청이 그 자체로 처리에 필요한 정보를 모두 담고 있어야 한다는 뜻이다. 서버가 상태를 기억하지 않으므로 어느 서버가 요청을 받아도 되어 서버를 늘리기 쉽다. 로그인 상태처럼 이어져야 하는 정보는 쿠키, 세션, 토큰으로 유지한다.

이렇게 바꿔 보세요

처음 설정으로 실행하면

  1. 브라우저 주소창에 localhost:8080 주소를 입력하면, 브라우저가 서버에 GET / 요청을 보냅니다. 이 요청에는 Cookie 헤더가 없습니다.
  2. 서버가 요청을 읽습니다. Cookie 헤더가 없어서 누구인지 알 수 없습니다. HTTP에서는 요청 하나하나가 따로여서, 서버는 이 요청이 전에 온 사람에게서 온 것인지 스스로는 알 수 없습니다. 이 서버는 Cookie 헤더로 visitor 값이 오면 "또 오셨군요, 값"을, 없으면 "처음 오셨군요"를 돌려주게 만들어 두었습니다. 이 서버 코드는 화면에 보이지 않습니다.
  3. 서버가 응답을 보냅니다. 본문은 "처음 오셨군요"이고, 코드 칸의 Set-Cookie: visitor=kim 줄이 붙어 있습니다. 이 줄은 "이 값을 맡아 두었다가 다음에 올 때 보여 달라"는 뜻입니다.
  4. 브라우저가 응답을 받고, Set-Cookie 줄의 visitor=kim을 자기 쪽에 저장합니다. 값이 저장되는 곳은 브라우저이고, 서버가 아닙니다. 이 서버에는 방문자를 적어 두는 곳이 없습니다.
  5. 브라우저가 같은 서버에 둘째 요청을 보냅니다. 이 서버가 맡긴 쿠키가 저장되어 있어서, 브라우저가 저장해 둔 값을 Cookie: visitor=kim 헤더로 요청에 붙입니다. 이 헤더를 붙이는 코드를 우리가 쓰지 않았습니다. 브라우저가 합니다.
  6. 서버가 요청을 읽습니다. Cookie 헤더에 visitor=kim이 있어서 "또 오셨군요, kim"을 본문으로 만듭니다. 서버는 이 사람을 기억하고 있던 것이 아니라, 요청에 실려 온 값을 읽었을 뿐입니다. Cookie 헤더가 와 있으므로 이번 응답에는 Set-Cookie 줄을 붙이지 않습니다.
  7. 브라우저가 둘째 응답을 받습니다. 본문은 "또 오셨군요, kim"입니다.

실행 결과

코드

HTTP/1.1 200 OK
Set-Cookie: visitor=kim
Content-Type: text/plain; charset=utf-8
(빈 줄)
처음 오셨군요

이 모형의 전제

서버는 Node.js 24.18.0의 net 모듈로 127.0.0.1의 빈 포트에 띄운 것 하나로, 요청의 헤더를 빈 줄까지 읽고 Cookie 헤더에 visitor 값이 있으면 "또 오셨군요, 값"을, 없으면 "처음 오셨군요"를 돌려줍니다. Set-Cookie: visitor=kim 줄은 설정이 켜져 있고 Cookie 헤더가 없던 요청의 응답에만 붙고, 보낸 뒤 연결을 닫습니다. 서버가 보낸 첫 응답은 코드 칸의 글과 줄 하나하나까지 같습니다(http 모듈로 만들면 Date 같은 헤더가 더 붙어 글이 달라져서 net으로 글자를 그대로 보냈고, Content-Length를 쓰지 않아 응답의 끝은 연결을 닫는 것으로 알립니다). 이 서버에는 방문자를 적어 두는 곳이 없어서, 쿠키 없는 새 클라이언트가 그 뒤에 요청하면 앞의 방문자를 알아보지 못했습니다. 클라이언트는 쿠키 규칙(RFC 6265)을 구현한 이 PC의 curl 8.21.0입니다. 쿠키를 저장하는 쪽은 curl -b와 -c에 같은 jar 파일을 주어(쿠키 엔진을 켜고 파일에 저장) 첫 응답 뒤 jar 파일을 읽어 저장된 쿠키를 얻었고, 사용자가 쿠키를 지우는 일은 둘째 요청에 새 빈 jar 파일을 주는 것으로 재현했습니다. 쿠키를 저장하지 않는 쪽은 쿠키 옵션이 없는 curl이고, 이 curl은 첫 응답의 Set-Cookie 줄을 받았는데도 둘째 요청에 Cookie 헤더를 붙이지 않았습니다. 여섯 가지 조합을 모두 실행해 저장된 쿠키, 서버가 둘째 요청에서 실제로 받은 Cookie 헤더, 둘째 응답을 대조했고, 두 요청의 헤더 전체와 두 응답의 원문, curl에 준 인자(Cookie 헤더를 직접 적는 인자가 없음)도 확인했습니다. 브라우저 대신 curl의 쿠키 엔진으로 대조했습니다. 브라우저도 같은 표준(RFC 6265)을 따르지만, 이 실습의 결과를 실제 브라우저에서 실행해 확인하지는 않았습니다. 문서로 확인한 것은 RFC 6265의 1절(서버가 Set-Cookie로 쿠키를 보내고 클라이언트가 이후 요청에 Cookie로 돌려보낼지 정한다), 3절과 3.1절(Set-Cookie: SID=31d4d96e407aad42를 받은 뒤 다음 요청에 Cookie: SID=31d4d96e407aad42가 실리는 예), 4.1절(Set-Cookie는 서버가 쿠키를 클라이언트에 보내는 응답 헤더), 4.2절(Cookie는 클라이언트가 저장한 쿠키를 서버에 돌려보내는 요청 헤더)이고, HTTP가 요청 하나하나를 따로 이해할 수 있는 무상태 프로토콜이라는 것은 RFC 9110의 3.3절을 따랐습니다. 화면의 localhost:8080은 예시 주소이고 실제 대조는 이 PC의 다른 포트에서 했습니다. 쿠키의 만료, 경로, 도메인, Secure, HttpOnly, SameSite 같은 속성은 다루지 않았고, 세부 동작은 "세부 동작 실습: 쿠키"에서 다룹니다. 이 서버 코드는 화면에 보이지 않습니다.

앞 실습: HTTP 응답 · 다음 실습: JSON

이 실습에 나오는 개념

이 실습에서 보는 것

설정

코드


      
    

그림

실행 비교

이렇게 바꿔 보세요