형식의 유효성을 일관성있게 유지하기 위해 내장함수 encodeURIComponent를 사용하여 이스케이프 처리를 해야 한다.
let name = "name";
let value = "John Smith";
//인코딩 처리 -> my%20name=John%20Smith
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
쿠키의 한계 1. encodeURIComponent로 인코딩한 후의 name=value 쌍이 4KB를 넘으면 쿠키에 저장할 수 없다. 2. 도메인 하나당 저장할 수 있는 쿠키의 수는 20여개로 한정되어 있다. 개수는 브라우저에 따라 차이가 있다.
쿠키의 옵션
쿠키에는 여러 옵션들이 존재한다.
개발자도구(F12) Application >> Cookies에서 쿠키를 확인할 수 있다.
1. Name & Value
데이터를 저장하고 읽는 데 사용하는 옵션으로 반드시 지정해주어야 한다.
document.cookie = "user=John"
2. Path
옵션을 입력하지 않으면 현재 도메인의 경로로 자동 입력된다.
특별한 경우가 아니라면 path=/와 같이 루트로 설정해 웹사이트의 모든 페이지에서 쿠키에 접근할 수 있도록 해야한다.
예를들어, path=/admin으로 설정한 쿠키는 /admin과 그 하위 경로에는 접근 가능하지만 /home과 같은 다른 경로에서는 사용할 수 없다.
document.cookie = "user=John; path=/"
3. Domain
쿠키에 접근 가능한 domain을 지정한다.
옵션을 입력하지 않으면 현재 domain의 경로로 자동 입력된다.
domain에 루트도메인을 명시적으로 설정하여 서브 도메인에서도 메인 도메인에서 생성한 쿠키 정보를 사용할 수 있다.
document.cookie = "user=John; domain=site.com"
4. Expires / Max-age
expires(유효 일자), max-age(만료 일자) 옵션을 지정하여, 쿠키의 만료 기간을 설정할 수 있다.
expires는 GMT 혹은 UTC포맷으로 설정해야한다.
세션 쿠키(Session Cookie) expires, max-age 옵션이 지정되어있지 않아, 브라우저가 닫힐 때 삭제되는 쿠키.
max-age는 expires의 대안으로, 쿠키 만료기간을 설정할 수 있게 해준다.
현재부터 설정하고자 하는 만료일시까지의 시간을 초로 환산한 값을 설정한다.
//expires
//toUTCString() 메서드를 사용하여 UTC포맷으로 쉽게 변환이 가능하다.
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;
//max-age
document.cookie = "user=John; max-age=3600";
5. Secure
해당 옵션을 설정 시, HTTPS로 통신하는 경우에만 쿠키가 전송된다.
// 설정한 쿠키는 HTTPS 통신시에만 접근할 수 있음
document.cookie = "user=John; secure";
6. HttpOnly
HttpOnly 옵션이 설정된 쿠키는 document.cookie로 쿠키 정보를 읽을 수 없다.
document.cookie = "user=John; httpOnly"
7. Samesite
XSRF 공격을 막기 위해 만들어진 옵션이다.
samesite 옵션을 XSRF 토큰 같은 다른 보안기법과 함께 사용하면 보안을 강화할 수 있다.
2017년 이전 버전의 브라우저에서는 samesite를 지원하지 않는다.
samesite(=strict) 사이트 외부에서 요청을 보낼 때, 해당 옵션이 있는 쿠키는 절대로 전송되지 않는다.
samesite=lax GET방식의 작업 혹은 최상위 레벨 탐색(브라우저 주소창에서 URL변경 등)에서의 작업이 이루어질 때만 쿠키가 서버로 전송된다.
document.cookie = "user=John; samesite"
쿠키 함수
getCookie(name)
정규 표현식을 사용하여 가장 빠르게 접근할 수 있다.
// 주어진 이름의 쿠키를 반환하는데,
// 조건에 맞는 쿠키가 없다면 undefined를 반환합니다.
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
setCookie(name, value, options)
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});
deleteCookie(name)
//만료 기간을 음수로 설정하여 쿠키를 삭제
function deleteCookie(name) {
setCookie(name, "", {
'max-age': -1
})
}