쿠키와 세션, 로컬 스토리지

Jeris·2023년 5월 9일
0

코드잇 부트캠프 0기

목록 보기
93/107

1. 쿠키

쿠키

쿠키(Cookie)는 인터넷 사용자의 컴퓨터나 모바일 장치에 저장되는 작은 데이터 파일입니다. 주로 웹사이트에서 사용되며, 웹사이트를 방문할 때마다 웹 브라우저에 의해 자동으로 생성됩니다. 이 쿠키는 사용자가 웹사이트를 방문할 때마다 다양한 정보를 저장하고 추적합니다.

쿠키는 다양한 용도로 사용됩니다. 예를 들어, 쇼핑몰 웹사이트에서는 쿠키를 사용하여 사용자가 쇼핑 카트에 담은 제품 목록이나 배송지 정보를 저장할 수 있습니다. 또한, 웹사이트의 로그인 정보나 개인화된 설정 등도 쿠키에 저장됩니다.

로그인에 성공했을 때 서버가 Set-Cookie 헤더로 쿠키 값을 보내주면 이걸 클라이언트가 저장해 두었다가, 서버에 리퀘스트를 보낼 때마다 매번 Cookie 헤더로 보내서 로그인 된 상태라는 걸 표시합니다. 웹 브라우저를 껐다 키거나 컴퓨터를 껐다 키더라도 쿠키 값은 유지되기 때문에 평소에 사이트를 한 번 로그인하면, 일정 기간 동안은 로그인하지 않아도 로그인이 유지됩니다.

쿠키는 일반적으로 개인 식별 정보를 저장하지 않으며, 사용자의 웹 브라우저에서 수동으로 삭제할 수 있습니다. 그러나 쿠키가 개인 정보를 수집하거나 불법적인 방법으로 사용될 수 있는 가능성도 있으므로, 사용자는 웹사이트에서 쿠키 사용에 대한 동의를 결정할 수 있습니다.

쿠키의 특징

  • 서버로부터 리스폰스로 쿠키를 받으면, 클라이언트에서는 별도로 작업을 해주지 않아도 알아서 웹 브라우저가 알아서 저장하고 리퀘스트를 보낼 때도 웹 브라우저가 알아서 보냅니다.
  • 자바스크립트를 통해서 쿠키 값을 추가, 수정, 참조할 수 있습니다.
  • 수명을 지정할 수 있습니다. 수명이 다한 쿠키는 알아서 지워집니다.

쿠키 사용법

서버에서 리스폰스할 때

서버에서 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;

자바스크립트로 사용하기

보통은 서버가 쿠키 값을 만들고, 클라이언트에서는 웹 브라우저에 맡기고 건드리지 않는 것이 권장됩니다. 하지만 클라이언트에서 자바스크립트로 쿠키를 생성/수정/참조 할 수도 있습니다.

  • 추가, 수정하기
    변수 할당처럼 보이지만 이 코드는 새로운 쿠키를 추가하거나 (기존에 session-id 라는 쿠키가 있다면) 수정하는 코드입니다.

    document.cookie = "session-id=1234; Domain=codeit.kr; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=2592000;";
    
  • 값 참조하기

    • document.cookie 값을 참조하면 모든 쿠키의 키와 값이 ; 문자로 구분된 문자열입니다.
    • split() 함수를 사용해서 직접 분리해서 사용하거나, 다양항 방법들을 사용할 수 있습니다. 스택오버플로우 링크 참고
    • cookie라는 NPM 패키지를 활용할 수도 있습니다.
  • 값 지우기
    Max-Age 값을 0으로 업데이트하면 (수명이 0) 지워집니다.

    document.cookie = "session-id; Max-Age: 0;";
    

알아두면 좋은 Attribute

Domain
브라우저가 쿠키를 보낼 도메인을 지정합니다. 예를 들어서 Domain=codeit.kr 이라고 하면 https://codeit.kr 은 물론이고 https://abc.codeit.kr, https://xyz.abc.codeit.kr 같은 서브 도메인(서브 도메인이란?)에 리퀘스트를 할 때도 쿠키를 보냅니다.

Path
브라우저가 쿠키를 보낼 경로를 지정합니다. 예를 들어서 Path=/ 라고 하면 / 아래에 있는 경로들, /abc, /abc/xyz 같은 경로에 리퀘스트를 보낼 때에도 모두 쿠키를 보냅니다.

HttpOnly ⭐️
document.cookie 값을 자바스크립트로 사용할 수 있으면, 해커들이 악성 코드를 사용자들에게 유포해 쿠키를 훔칠 수 있습니다. (게시판에 자바스크립트를 올려서 쿠키를 탈취하는 Cross-Site Scription 사례)

로그인 정보 같은 민감한 정보는 되도록이면 자바스크립트로 조작하면 안됩니다. HttpOnly 를 사용하면 쿠키를 자바스크립트로 사용하지 못하게 막을 수 있습니다.

Secure ⭐️
Secure 를 지정하면 HTTPS 리퀘스트를 보낼 때만 쿠키를 보냅니다. 참고로 SameSite=None 을 지정하면 반드시 Secure도 함께 지정해야 합니다.

SameSite ⭐️
자바스크립트를 사용하면 현재 사이트에서 다른 사이트로 리퀘스트를 보낼 수 있고, 사이트의 링크를 클릭하면 웹 브라우저는 다른 사이트로 GET 리퀘스트를 보내며 이동합니다. 그리고 이미지 파일을 다운 받거나 할 때도 GET 리퀘스트를 보내서 받습니다.

예를 들어서 codeit.kr이라는 사이트에서 쿠키를 발급해서 사용자가 저장하고 있는데, 사용자가 hacker-site.com 이라는 악성 사이트에 접속한다고 합시다. 이 악성 사이트는 codeit.kr 이라는 사이트로 리퀘스트를 보내서 개인정보를 탈취하는 사이트입니다. 악성 사이트에서 코드잇으로 리퀘스트를 보낼 때 쿠키가 함께 간다면 위험해질 수 있습니다.

이런 공격을 크로스 사이트 요청 위조 (Cross-site request forgery, CSRF, XSRF)라고 합니다. XSRF를 방지하기 위해서 제3자 사이트(Third-party site)에서 쿠키를 보내지 못하게 SameSite 를 지정해야 합니다.

SameSite 속성의 값에는 Strict, Lax (아무것도 지정하지 않았을 때 기본값), None이 있습니다. 다음은 SameSite 값에 따른 쿠키 전송 유무를 간략히 정리한 표입니다:

ExpiresMax-Age ⭐️
쿠키의 수명을 지정하는 속성입니다. Expires로 만료될 시기를 지정하거나, Max-Age 로 쿠키의 수명을 지정할 수 있습니다.

  • 세션 쿠키(Session Cookie) ExpiresMax-Age 를 지정하지 않으면 만들 수 있습니다. 세션 쿠키는 브라우저를 닫으면 지워지는 쿠키입니다.
  • 영속적인 쿠키(Persistent Cookie) ExpriesMax-Age 로 수명을 지정해서 만들 수 있습니다. 수명이 다하면 지워지는 쿠키입니다.

개인 정보와 쿠키

예전에 구글, 페이스북 등 빅테크들이 쿠키를 사용해서 사용자의 정보를 과도하게 수집하고 자사 광고에 활용해 논란이된 적이 있습니다. 그래서 유럽 연합에서는 개인정보의 범위를 넓혀 직간접적으로 개개인을 식별할 수 있는 데이터까지 개인정보로는 규정을 만들게 되었습니다. 여기에는 쿠키 데이터도 포함됩니다.

따라서 쿠키를 사용하는 경우 GDPR(일반 정보 보호 규정; General Data Protection Regulation) 규정에 따르면 개인정보 이용목적을 안내하고 사용자의 동의를 받는 등의 절차가 필요합니다. 그래서 최근 많은 사이트들이 처음 들어가면 팝업을 띄우고 동의를 받습니다.

[모비랩의 테크인사이드] 마케터라면 필수적으로 알아야 할 'GDPR(일반 정보 보호 규정)' 이해 - 모비인사이드 MOBIINSIDE 참조

참고하면 좋은 자료

쿠키, 세션, 캐시가 뭔가요?
HTTP 쿠키 - HTTP | MDN
Set-Cookie - HTTP | MDN
브라우저 쿠키와 SameSite 속성 / seob.dev
react-cookie 쉽게 사용하기
Cross Site Request Forgery (CSRF) | OWASP Foundation


2. 세션 스토리지와 로컬 스토리지

세션 스토리지와 로컬 스토리지

세션 스토리지(Session storage)와 로컬 스토리지(Local storage)는 모두 웹 브라우저에서 제공하는 클라이언트 사이드 저장소입니다. 이 두 가지 저장소는 모두 키-값 쌍의 데이터를 저장하고, JavaScript를 사용하여 데이터를 추가, 수정, 삭제 및 검색할 수 있습니다.

하지만 세션 스토리지와 로컬 스토리지는 사용 방법과 데이터의 지속성에 대한 차이가 있습니다.

세션 스토리지는 데이터를 일시적으로 저장하는 경우에 유용하고, 로컬 스토리지는 영구적으로 데이터를 저장하는 경우에 유용합니다. 예를 들어, 로그인 정보와 같은 일시적인 데이터는 세션 스토리지에 저장할 수 있으며, 사용자 기본 설정과 같은 영구적인 데이터는 로컬 스토리지에 저장할 수 있습니다.

세션 스토리지

세션 스토리지는 웹 브라우저의 세션 기간 동안 데이터를 저장합니다. 세션 기간 동안에는 사용자가 웹 사이트에 접속하고 브라우저를 종료할 때까지를 의미합니다. 브라우저를 종료하면 세션 스토리지에 저장된 모든 데이터가 삭제됩니다.

현재 탭에서만 유효한 저장소이기 때문에 탭을 닫으면 데이터가 사라지고 다른 탭과 데이터는 공유되지 않습니다.

로컬 스토리지

로컬 스토리지는 데이터를 영구적으로 저장합니다. 사용자가 브라우저를 닫아도 데이터는 계속 유지됩니다. 이러한 특징은 사용자가 웹 사이트를 다시 방문할 때 데이터를 유지할 수 있도록 합니다.

해당 사이트에서 유효한 저장소이기 때문에 탭을 닫거나 브라우저를 닫아도 데이터가 유지되고 여러 탭 사이에서도 데이터가 공유됩니다.

쿠키와 다른 점

  • 클라이언트가 만들고 관리하는 데이터입니다.
  • 자바스크립트로 편리하게 조작할 수 있습니다.
  • 만료 기간(수명)이 없습니다.
  • 쿠키보다 사용할 수 있는 용량이 큽니다.

스토리지가 변경되었을 때 처리하기

스토리지가 변경되었을 때 'storage' 라는 이벤트가 발생합니다.

window.addEventListener("storage", () => {
  const showSidebar = localStorage.getItem('show-sidebar') === 'true';
    // showSidebar 값 적용하기
});

Window: storage event - Web APIs | MDN

참고하면 좋은 자료

Web Storage API - Web API | MDN
웹용 스토리지
localStorage와 sessionStorage


3. 활용 사례

쿠키

로그인

(세션 기반 인증의 경우) 처음에 세션 ID를 쿠키로 보내 줍니다. 로그인에 성공하면 서버 쪽에서 세션 상태를 업데이트 합니다.

(토큰 기반 인증의 경우) 로그인에 성공하면 서버가 토큰을 발급해 쿠키로 보내 줍니다.

세션 기반, 토큰 기반 인증에 대해서 살펴보기 (참고 토픽 링크)

하루동안 팝업 다시 보지 않기

사용자가 ‘하루 동안 다시 보지 않기’를 체크하고 닫으면 클라이언트가 수명이 1일인 쿠키를 만듭니다.

다음에 접속했을 때는 이 쿠키를 확인해서 팝업을 보여주지 않습니다.

로컬 스토리지로 구현하기 참조

장바구니

(세션 기반 인증을 사용하는 경우) 처음 세션 ID를 쿠키로 보내 줍니다. 이 세션 ID를 기반으로 서버에서 장바구니 정보를 저장합니다. (예시)
(로컬 기반 인증을 사용하는 경우) 브라우저에서 localStorage 객체를 사용하여 데이터를 로컬 스토리지에 저장합니다. JavaScript를 사용하여 데이터를 로드하고 편집하며, 변경 사항을 로컬 스토리지에 저장합니다. (예시)

로컬 스토리지를 사용하면 영구적으로 데이터를 저장할 수 있으므로 더 넓은 범위의 장바구니 데이터를 저장하고자 한다면 로컬 스토리지가 더 적합합니다. 반면, 세션 스토리지는 더 강력한 보안성을 제공하므로 민감한 데이터를 다루는 경우에는 이를 사용하는 것이 좋습니다.

세션 스토리지, 로컬 스토리지

초안(draft) 임시 저장하기
텍스트를 입력하다가 실수로 창을 닫아 버리더라도 내용이 남아있게 할 수 있습니다.

  • https://stackedit.io/
    • 로컬 스토리지를 사용해 구현할 수 있습니다.
    • 실제로는 로컬 스토리지와 유사하지만 좀 더 데이터베이스처럼 쓸 수 있는 IndexedDB로 구현되어 있습니다. (IndexedDB란?)

  • slack.com
    • 채팅창에 입력하다가 창을 닫더라도 내용이 저장됩니다.
    • 기본적으로 초안을 로컬 스토리지에 저장합니다
    • 주기적으로 서버에도 초안을 저장합니다. 그래서 모바일 앱에서도 초안을 확인할 수 있습니다.

웹 앱
웹 기반으로 만들어진 프로그램(웹 앱)들은 세션, 로컬 스토리지를 적극적으로 사용합니다.

  • draw.io
    • 온라인에서 다이어그램을 그리는 프로그램.
    • 프로그램을 사용하면서 유지해야 할 각종 설정 값을 로컬 스토리지에 저장하고 있습니다.
    • 예시: 테마를 바꾸고 로컬 스토리지의 .drawio-config를 확인해 보세요.

  • figma.com
    • 웹 기반으로 만들어진 디자인 협업 도구입니다.
    • 예시: 피그마에서 로컬 스토리지의 show-sidebar의 값을 0 또는 1로 바꿔 보세요.

  • notion.so
    • 로컬 스토리지에 굉장히 많은 데이터를 저장 중
    • LRUCache를 로컬 스토리지에 저장하는 것으로 보입니다. (LRU캐시란?) 쉽게 말해서 자주 쓰는 데이터를 로컬 스토리지에 캐싱해두는 용도로 사용 중인 걸로 보입니다.

Feedback

  • 참고 자료들을 포스팅해보자.
  • 쿠키는 현재 진행중인 프로젝트에서 급히 필요한 내용이었다.

Reference

profile
job's done

0개의 댓글