Skip to main content

4.1 쿠키와 document.cookie

쿠키는 브라우저에 저장되는 작은 크기의 문자열이다.

  • 웹서버가 header에 Set-Cookie에 내용을 전달하면, 브라우저는 이를 저장.
  • 그리고 다음 요청때마다 Cookie 요청 헤더에 넣어서 보낸다.

쿠키에 세션 식별자(session identifier)을 담아서 사용자를 식별하는데 사용한다.

제약사항

  • name=value 쌍은 4KB를 넘을 수 없다.
  • 도메인 하나당 저장할 수 있는 쿠키의 개수는 20여 개 정도로 한정

쿠키 읽기/쓰기

// 쿠키 읽기  
// name=value 쌍으로 구성되어있고, 각 쌍은 ;로 구분
alert( document.cookie ); // cookie1=value1; cookie2=value2;...

// 쿠키 쓰기
document.cookie = "user=John"; // 이름이 'user'인 쿠키의 값만 갱신함
alert(document.cookie); // 모든 쿠키 보여주기
// cookie는 데이터 프로퍼티가 아닌 접근자(accessor) 프로퍼티입 이다.

// 이스케이프 처리
// 특수 값(공백)은 인코딩 처리해 줘야 합니다.
let name = "my name";let value = "John Smith";
// 인코딩 처리를 해, 쿠키를 my%20name=John%20Smith 로 변경하였습니다.
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
alert(document.cookie); // ...; my%20name=John%20Smith



쿠키 옵션들

  • 옵션은 key=value 뒤에 나열하고 ;로 구분zustand-01
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"

path

특정 서브 path 단위로 쿠키를 격리하고 싶을때

  • 특별한 경우가 아니라면, path 옵션을 path=/같이 루트로 설정해 웹사이트의 모든 페이지에서 쿠키에 접근할 수 있도록 합시다.
  • path=/admin 옵션을 사용하여 설정한 쿠키는 /admin과 /admin/something에선 볼 수 있지만, /home 이나 /adminpage에선 볼 수 없습니다.

domain

같은 1차 도메인간의 쿠키를 공유하고 싶을때

  • domain
// site.com에서 쿠키를 설정함
document.cookie = "user=John"
// site.com의 서브도메인인 forum.site.com에서 user 쿠키에 접근하려 함
alert(document.cookie); // 찾을 수 없음
// site.com에서
// 서브 도메인(*.site.com) 어디서든 쿠키에 접속하게 설정할 수 있습니다.
document.cookie = "user=John; domain=site.com"
// 이렇게 설정하면 forum.site.com와 같은 서브도메인에서도 쿠키 정보를 얻을 수 있습니다.
alert(document.cookie); // user=John 쿠키를 확인할 수 있습니다.

expires와 max-age

"세션 쿠키(session cookie)": expires(유효 일자)나 max-age(만료 기간) 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 삭제됩니다.

  • 이런 쿠키를 "세션 쿠키(session cookie)" 라고 부릅니다.
  • expires 나 max-age 옵션을 설정하면 브라우저를 닫아도 쿠키가 삭제되지 않습니다.
// 지금으로부터 하루 후
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;
---
// 1시간 뒤에 쿠키가 삭제됩니다.
document.cookie = "user=John; max-age=3600";
// 만료 기간을 0으로 지정하여 쿠키를 바로 삭제함
document.cookie = "user=John; max-age=0";

secure

이 옵션을 설정하면 HTTPS로 통신하는 경우에만 쿠키가 전송됩니다.

// (https:// 로 통신하고 있다고 가정 중)
// 설정한 쿠키는 HTTPS 통신시에만 접근할 수 있음
document.cookie = "user=John; secure";

samesite

XSRF 공격

  • 브라우저의 특성 중 하나가 evil.com 사이트에서 <form action="https://bank.com/pay"> 을 작동시킬 수 있다.
  • 이때 evil.com에서 원하는 데이터를 form에 넣고, - 조작된 정보
  • 죄없는 사용자의 쿠키는 브라우저가 알아서 같이 보낸다. - 사용자 인증 관련 토큰

samesite=strict

  • 제3의 도메인에서 요청이 이뤄질 땐 쿠키가 전송되지 않죠.
  • 메일에 있는 링크를 따라 접속하거나
  • evil.com과 같은 사이트에서 폼을 전송하는 경우 등

samesite=lax

  • strict 보다 느슨한 보안정책이며, 아래 2가지 경우에 허용된다.
  • 1.“안전한” HTTP 메서드인 경우(예: GET 방식. POST 방식은 해당하지 않음).
  • 2.작업이 최상위 레벨 탐색에서 이루어질 때(브라우저 주소창에서 URL을 변경하는 경우).
    • 대다수의 작업은 이 조건을 충족합니다.
    • 하지만 <iframe>안에서 탐색이 일어나는 경우는 최상위 레벨 탐색이 아니기 때문에 이 조건을 충족하지 못합니다. AJAX 요청 또한 탐색 행위가 아니므로 이 조건을 충족하지 못합니다.

httpOnly

이 옵션은 자바스크립트 같은 클라이언트 측 스크립트가 쿠키를 사용할 수 없게 합니다.

  • document.cookie를 통해 쿠키를 볼 수도 없고 조작할 수도 없습니다.

쿠키 관련 함수

// 주어진 이름의 쿠키를 반환하는데,
// 조건에 맞는 쿠키가 없다면 undefined를 반환합니다.
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
---
function setCookie(name, value, options = {}) {

options = {
path: '/',
// 필요한 경우, 옵션 기본값을 설정할 수도 있습니다.
...options
};

if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}

let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);

for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}

document.cookie = updatedCookie;
}

// Example of use:
setCookie('user', 'John', {secure: true, 'max-age': 3600});
---
function deleteCookie(name) {
setCookie(name, "", {
'max-age': -1
})
}

부록: 서드 파티 쿠키

서드파티 쿠키의 수집원리

  • site.com에 이미지 배너를 통해서 <img src="https://ads.com/banner.png"> ads.com로 부터 쿠키설정이 된다.

  • site.com에 이미지 배너를 통해서 <img src="https://ads.com/banner.png"> ads.com에 쿠키와 함께 요청 된다.(추적1)

  • othersite.com에 이미지 배너를 통해서 <img src="https://ads.com/banner.png"> ads.com에 쿠키와 함께 요청 된다.(추적2)

  • 광고회사는 사용자의 이용 행태를 추적하고, 광고를 제공하기 위해 오래전부터 서드 파티 쿠키를 사용하고 있습니다.

  • 서드파티 쿠키는 쿠키를 설정한 도메인에 종속되기 때문에 ads.com은 사용자가 어떤 사이트를 방문했는지 추적할 수 있습니다.

부록: GDPR

  • 쿠키를 추적하는 경우 사용자로부터 명시적인 허가를 얻어야 한다는 것이 이 법령