사용자가 성공적인 로그인을 하면 서버는 클라이언트에 인증서를 보낸다. 클라이언트가 이 인증서를 가져오면 어떤 사람인지 구별하는 것이다. 클라이언트는 리퀘스트를 보낼 때마다 이 인증서를 함께 보내야 한다. → 이럴 때 쿠키를 쓴다.
서버에서 set-cookie
헤더를 리스폰스로 보내주면 웹 브라우저는 알아서 쿠키 값을 저장한다.
Set-Cookie: session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;
여기서 맨 앞의 session-id
는 쿠키의 Key에 해당하는 값
1234
는 Value에 해당하는 값
domain
, path
, samesite
등은 쿠키의 Attribute에 해당하는 값 (헤더 이름이나 Attribute 이름들은 대소문자를 구분하지 않기 때문에 set-cookie
, domain
, path
, samesite
로 쓸 수도 있음)
리퀘스트를 보낼 때 주소에 해당하는 쿠키가 저장되어 있다면 웹 브라우저가 알아서 쿠키를 보내준다.
Cookie: session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;
보통은 서버가 쿠키 값을 만들고, 클라이언트에서는 웹 브라우저에 맡기고 건드리지 않는 것이 권장된다. 하지만 클라이언트에서 자바스크립트로 쿠키를 생성/수정/참조 할 수도 있다.
document.cookie = "session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;";
document.cookie
값을 참조하면 모든 쿠키의 키와 값이 ;
문자로 구분된 문자열split()
함수를 사용해서 직접 분리해서 사용하거나, 스택오버플로우사용 Get cookie by nameMax-Age
값을 0으로 업데이트하면 (수명이 0) 지워진다.
document.cookie = "session-id; Max-Age: 0;";
Domain=codeit.kr
이라고 하면 https://codeit.kr
은 물론이고 https://abc.codeit.kr
, https://xyz.abc.codeit.kr
같은 서브 도메인에 리퀘스트를 할 때도 쿠키를 보낸다.Path=/
라고 하면 /
아래에 있는 경로들, /abc
, /abc/xyz
같은 경로에 리퀘스트를 보낼 때에도 모두 쿠키를 보낸다.document.cookie
값을 자바스크립트로 사용할 수 있으면, 해커들이 악성 코드를 사용자들에게 유포해 쿠키를 훔칠 수 있다. 로그인 정보 같은 민감한 정보는 되도록이면 자바스크립트로 조작하지 말기. HttpOnly
를 사용하면 쿠키를 자바스크립트로 사용하지 못하게 막을 수 있다.Secure
를 지정하면 HTTPS 리퀘스트를 보낼 때만 쿠키를 보낸다. (SameSite=None
을 지정하면 반드시 Secure
도 함께 지정해야 함)codeit.kr
이라는 사이트에서 쿠키를 발급해서 사용자가 저장하고 있는데, 사용자가 hacker-site.com
이라는 악성 사이트에 접속한다고 하면) 이 악성 사이트는 codeit.kr
이라는 사이트로 리퀘스트를 보내서 개인정보를 탈취하는 사이트 → 악성 사이트에서 코드잇으로 리퀘스트를 보낼 때 쿠키가 함께 간다면 개인정보를 탈취당한다. → 크로스 사이트 요청 위조 (Cross-site request forgery, CSRF, XSRF) CSRF를 방지하기 위해서 제3자 사이트(Third-party site)에서 쿠키를 보내지 못하게 SameSite
를 지정해야 한다. SameSite
속성의 값에는 Strict
, Lax
(아무것도 지정하지 않았을 때 기본값), None
이 있다.
SameSite=Strict | SameSite=Lax | SameSite=None | |
---|---|---|---|
다른 사이트에서 우리 사이트로 리퀘스트를 보낼 때 | X | X | O |
다른 사이트에서 이미지 파일 등을 받을 때 | X | X | O |
다른 사이트에서 사용자가 링크를 클릭해 우리 사이트로 이동할 때 | X | O | O |
우리 사이트에서 우리 사이트로 리퀘스트를 보낼 때 | O | O | O |
Expires
와 Max-Age
⭐️Expires
로 만료될 시기를 지정하거나, Max-Age
로 쿠키의 수명을 지정할 수 있다.Expires
나 Max-Age
를 지정하지 않으면 만들 수 있다. (세션 쿠키는 브라우저를 닫으면 지워지는 쿠키)Expries
나 Max-Age
로 수명을 지정해서 만들 수 있다. (수명이 다하면 지워지는 쿠키)브라우저 쿠키와 SameSite 속성 / seob.dev
Cross Site Request Forgery (CSRF) | OWASP Foundation
쿠키는 서버에서 만들고, 클라이언트는 거의 건드리지 않는다. 그런데 사이트에 따라서는 클라이언트에서만 사용하는 데이터인데, 저장해 놓고 사용하고 싶은 경우가 있다.
→ 세션 스토리지(Session Storage)와 로컬 스토리지(Local Stroage)
// 값을 저장하는 코드. (이미 값이 있다면) 수정하는 코드
const data = inputElement.value;
sessionStorage.setItem('draft', data);
// 값을 참조해서 사용할 때
const draftData = sessionStorage.getItem('draft');
// 값 지우기
sessionStorage.removeItem('draft');
// 사용자가 사이드바 감추기 버튼을 클릭했을 때
// 값을 저장, 수정
localStorage.setItem('show-sidebar', 'false');
// 사용자가 처음 접속했을 때
const showSidebar = localStorage.getItem('show-sidebar') === 'true';
// 값 지우기
localStorage.removeItem('show-sidebar');
스토리지가 변경되었을 때 'storage'
라는 이벤트가 발생한다.
window.addEventListener("storage", () => {
const showSidebar = localStorage.getItem('show-sidebar') === 'true';
// showSidebar 값 적용하기
});
Web Storage API - Web API | MDN
로그인
(세션 기반 인증의 경우)
처음에 세션 ID를 쿠키로 보낸다. 로그인에 성공하면 서버 쪽에서 세션 상태를 업데이트한다.
(토큰 기반 인증의 경우)
로그인에 성공하면 서버가 토큰을 발급해 쿠키로 보내준다.
하루동안 팝업 다시 보지 않기
하루 동안 다시 보지 않기’를 체크하고 닫으면 클라이언트가 수명이 1일인 쿠키를 만든다.
다음에 접속했을 때는 이 쿠키를 확인해서 팝업을 보여주지 않는다.
👇🏻만약 로컬 스토리지로 구현한다면?👇🏻
How to Set Expiry Time (TTL) for LocalStorage With Javascript
장바구니
(세션 기반 인증을 사용하는 경우)
처음 세션 ID를 쿠키로 보낸다. 이 세션 ID를 기반으로 서버에서 장바구니 정보를 저장한다.
초안(draft) 임시 저장하기
텍스트를 입력하다가 실수로 창을 닫아 버리더라도 내용이 남아있게 할 수 있다.
웹 앱
웹 기반으로 만들어진 프로그램(웹 앱)들은 세션, 로컬 스토리지를 적극적으로 사용한다.