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
- 쿠키를 추적하는 경우 사용자로부터 명시적인 허가를 얻어야 한다는 것이 이 법령