쿠키라는 것은, RFC 6265 명세에서 정의한 HTTP 프로토콜의 일부입니다.
서버에서는 http 헤더에 "Set-Cookie" 프로퍼티를 담으면, 요청을 받은 브라우저에서는 해당 쿠키를 저장합니다.
브라우저에서는 새로운 http 요청시에 저장하고 있는 쿠키를 요청 헤더에 항상 담아서 전달합니다. (단, 같은 도메인에 한정)
http 요청에 쿠키를 전달하기 위한 조건
서로다른 도메인간의 자원요청은 보안상의 이유로 기본적으로 제한되어있습니다.
하지만 CORS 설정을 해줌으로써, 이를 가능케하는데요.
쿠키는 단순히 CORS 설정을 넘어서 조금 더 세밀한 설정을 해주어야합니다.
브라우저와 node 예시 코드를 살펴보겠습니다.
front : localhost:3000, server:localhost:4000 환경입니다.
// 브라우저
const res = await fetch('http://localhost:4000', {
credentials: 'include',
});
브라우저에서 http 요청에 쿠키를 담아서 전송해야합니다.
(1) fetch API 는 옵션으로 credentials:'include' 를 설정하면, 브라우저에 저장된 쿠키를 http 헤더에 담고,
응답의 헤더 중 'Set-Cookie' 헤더를 읽어냅니다.
// 서버
const http = require('http');
const server = http.createServer((req, res) => {
const origin = req.headers.origin;
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', origin); // CORS
res.setHeader('Access-Control-Allow-Credentials', 'true'); // cookie
res.setHeader('Set-Cookie', 'name=kong2'); // cookie 저장하도록 명령
res.write(JSON.stringify('hello'));
res.end();
});
server.listen(4000, () => {
console.log('Server is running on port 4000');
});
(2) 서버는 'Access-Control-Allow-Origin' 으로 CORS 를 허용해야하고, 여기서는 "*"(와일드카드) 를 사용할 수 없습니다.
쿠키는 정확히 도메인을 명시해야하며, 편법으로 요청의 origin 값을 설정하도록 하였습니다.
(3) 위단계 까지만 하면 CORS 만 허용하고, 쿠키는 허용하지 않습니다.
쿠키를 브라우저가 해석하게 하도록 하려면 'Access-Control-Allow-Credentials' 헤더를 'true' 로 추가 설정해줘야 합니다.
❗️CORS 는 origin 기준으로 허용 여부를 결정하는 것이고, Cookie 는 domain 기준입니다.
예를들어서 localhost:3000 과 localhost:4000 은 CORS 의 제약에 걸리고,
Cookie 는 localhost 과 naver.com 간에는 절대 전달되지 않습니다.
쿠키 읽기
브라우저에서도 현재 저장된 쿠키를 읽을 수 있습니다.
document.cookie // name=kong2
쿠키 쓰기
documnet.cookie = 'key=value';
document.cookie 는 접근자 프로퍼티(getter, setter)입니다. 그러므로 위와 같이 작성해도, 나머지 값들을 덮어쓰는 것이 아닌 추가하게 됩니다.
';' 로 구분하여 여러 쿠키, 옵션 등을 저장할 수 있습니다.
쿠키의 name, value 에는 제약이 없지만, 유효성을 위해서 반드시 encodeURIComponent 를 사용하여 이스케이프 처리해주는 것이 좋습니다.
const encoded = encodeURIComponent(str);
document.cookie = `name=${encoded};`;
쿠키의 제약사항
- 하나의 쿠키는 4KB 를 넘을 수 없습니다.
- 도메인 하나당 쿠키는 20여개로 한정되어 있고, 개수는 브라우저마다 조금씩 다릅니다.
쿠키 옵션
쿠키는 다양한 옵션과 함께 다룰 수 있습니다.
document.cookie = 'name=kong; path=/home' // /home 하위 경로에서만 유효한 쿠키
document.cookie = 'name=kong; domain=naver.com' // naver.com 도메인에서만 유효한 쿠키, 직접 설정해야만 서브도메인까지 유효합니다.
document.cookie = 'name=kong; max-age=3' // 생성 시점으로 부터 3초 동안 유효한 쿠키
document.cookie = 'name=kong; max-age=0' // 만료시간을 조정함으로써, 쿠키를 제거할 수 있습니다.
document.cookie = 'name=kong; expires=Fri, 06 Oct 2023 05:30:10 GMT'; // 정확히 UTC 시간에 만료되는 쿠키 , new Date(Date.now() + 1000 * 3).toUTCString(); 이렇게 만들어낼 수 있습니다.
document.cookie = 'name=kong; secure;' // https 환경에서만 유효한 쿠키
document.cookie = 'name=kong; samesite' // XSRF 공격을 막기위한 옵션으로, 요청하는 사이트가 http 요청 사이트의 주소와 같아야만 쿠키를 전송합니다. 공백, strict, lax 옵션이 있습니다.
+ httpOnly
이 옵션은 서버에서 'Set-Cookie' 할 때 설정할 수 있는 옵션으로, document.cookie 에서 접근이 불가능한 쿠키를 만듭니다.
역시나, 보안상의 이유로 만들어진 옵션입니다.
과거에 쿠키를 수집해서, 비행기 티켓, 숙박비 등을 조작하는 사례가 있었던 것이 기억납니다.
이렇게 쿠키는 사용자의 중요한 정보를 담는 용도로 사용되기 도하는데요.
이것 때문에 각 브라우저마다 쿠키에대한 제약을 많이 걸어두었습니다.
서드파티 쿠키라고 해서, 현재 도메인이 아닌, 다른 도메인에서 쿠키를 설정하는 것을 말하는데, 예를들어 이미지를 로딩하는데, 이미지 요청 헤더에 'Set-Cookie' 가 있다면, 의도치 않게 다른도메인의 쿠키를 저장하게 됩니다.
이런 방식는 광고회사에서 사용자의 이용 형태를 추적할 때 사용되곤 합니다.
Safari 의 경우 서드파티 쿠키를 전면 불허 하고, Firefox 는 블랙리스트를 만들어, 서드파티 쿠키를 차단합니다.
또한 유럽에서는 GDPR 이라는 사용자 개인 정보 보호를 강제하는 법령이 있습니다.
쿠키를 추적하는 경우 사용자의 명시적인 허가가 필요한다는 것인데, 요즘 사이트 돌아다니다 보면 쿠키 허용하겠냐는 팝업이 자주뜨는 이유가 이것 때문입니다.
다만 쿠키를 단순 정보 저장용도로만 사용한다면 신경쓸 필요는 없습니다.
'FE > browser' 카테고리의 다른 글
[browser] IndexedDB (0) | 2023.10.07 |
---|---|
[browser] 브라우저의 Storage (0) | 2023.10.06 |
[browser] Blob 다루기 (0) | 2023.10.05 |
[Browser] Service Worker 로 push notification 구현하기 (0) | 2023.09.21 |
[Browser] Web Worker 와 Service Worker (0) | 2023.09.20 |