[WEB] localStorage, sessionStorage, cookie

Lemon·2022년 11월 3일
0

CS

목록 보기
13/17

🔗 참고링크
sessionStorage
https://ko.javascript.info/localstorage
https://velog.io/@ejchaid/localstorage-sessionstorage-cookie의-차이점
링크 학습 후 재 정리 한 것입니다.

Web Storage

HTML5에는 웹의 데이터를 클라이언트에 저장할 수 있는 새로운 자료구조인 웹 스토리지 객체(web storage object) 스펙이 포함되어 있다.
웹 스토리지 객체(web storage object)는 key/value 로 데이터를 저장하고 key를 기반으로 데이터를 조회하는 패턴이다.
웹 스토리지 객체(web storage object)인 localStorage와 sessionStorage는 브라우저 내에 키-값 쌍을 저장할 수 있게 해준다. localStorage 는 영구저장소, sessionStorage 는 임시저장소인데, 이 둘을 따로 두어 데이터의 지속성을 구분해서 응용 환경에 맞게 선택할 수 있다.
웹 스토리지 객체(web storage object)는 기존 웹 환경의 쿠키(Cookie)와 매우 유사한 개념이다. 쿠키의 단점을 극복하는 개선점이 도입되었다. 그러나 쿠키는 여전히 유효하고 꽤 적절한 클라이언트 저장 도구임이 틀림없기때문에 HTML5에서 스펙을 새로 추가했지만 쿠키를 배제한다는 의미는 아니다. 여전히 쿠키는 이용 가능하다.


쿠키 이외에도 다른 방식을 사용하는 이유

쿠키를 사용하면 브라우저에 데이터를 저장할 수 있는데, 왜 또 다른 객체를 사용해 데이터를 저장하는 걸까?

  • 쿠키는 매번 서버로 전송된다.
    • 쿠키와 다르게 웹 스토리지 객체는 네트워크 요청 시 서버로 전송되지 않습니다. 이런 특징 때문에 쿠키보다 더 많은 자료를 보관할 수 있습니다. (이 특징이 꽤나 유용한 특징이다.) 대부분의 브라우저가 최소 2MB 혹은 그 이상의 웹 스토리지 객체를 저장할 수 있도록 해줍니다. 또한 개발자는 브라우저 내 웹 스토리지 구성 방식을 설정할 수 있습니다.
  • 단순 문자열을 넘어(스크립트) 객체정보를 저장할 수 있다.
  • 용량 제한이 없다.
    • 쿠키는 개수와 용량 제한이 있다. 하나의 사이트에서 저장할 수 있는 최대 쿠키 수는 20개다. 그리고 최대 쿠키 크기는 4KB로 제한되어있다. 그러나 웹 스토리지 객체(web storage object)에는 이런 제한이 없다. 그러나 쿠키도 하위키를 이용하면 이런 제한을 일부 해소할 수 있다. 그리고 대부분 쿠키의 제한까지 데이터를 저장할 일이 없다.
  • 쿠키와 또 다른 점은 서버가 HTTP 헤더를 통해 스토리지 객체를 조작할 수 없다는 것입니다. 웹 스토리지 객체 조작은 모두 자바스크립트 내에서 수행됩니다.
  • 웹 스토리지 객체는 도메인·프로토콜·포트로 정의되는 오리진(origin)에 묶여있습니다. 따라서 프로토콜과 서브 도메인이 다르면 데이터에 접근할 수 없습니다.
  • 영구 데이터 저장이 가능하다.
    • 쿠키는 만료일자를 지정하게 되어 있어 언젠가 제거된다. 만약 만료일자를 지정하지 않으면 세션 쿠키가 된다. 만일 영구 쿠키를 원한다면 만료 일자를 굉장히 멀게 설정하여 해결할 수 있다.
    • 웹 스토리지는 만료 기간이 없다. 즉, 영구적으로 존재하는 것이다.

LocalStorage와 SessionStorage

웹 스토리지 객체(web storage object)는 데이터의 지속성과 관련하여 두 가지 용도의 저장소를 제공한다.
웹 스토리지 객체(web storage object)는 쿠키와 마찬가지로 사이트의 도메인 단위로 접근이 제한된다. A 도메인에서 저장한 데이터는 B 도메인에서 조회할 수 없다는 것이다. 이는 데이터 보안 측면에서 당연하다.
두 스토리지 객체는 동일한 메서드와 프로퍼티를 제공합니다.

  • setItem(key, value) – 키-값 쌍을 보관한다.
  • getItem(key) – 키에 해당하는 값을 받아온다.
  • removeItem(key) – 키와 해당 값을 삭제한다.
  • clear() – 모든 것을 삭제한다.
  • key(index) – 인덱스(index)에 해당하는 키를 받아온다.
  • length – 저장된 항목의 개수를 얻는다.

LocalStorage

  • localStorage의 데이터는 만료되지 않는다.
    • 브라우저를 종료해도 데이터는 보관되어 다음 접속에도 그 데이터를 사용할 수 있다.

저장한 데이터를 명시적으로 지우지 않는 이상 영구적으로 보관이 가능하다.
도메인마다 별도로 localStorage가 생성된다.
Windows 전역 객체의 LocalStorage라는 컬렉션을 통해 저장과 조회가 이루어진다.

  • 오리진이 같은 경우 데이터는 모든 탭과 창에서 공유된다.
  • 브라우저나 OS가 재시작해도 데이터가 파기되지 않는다.
// LocalStorage.js
localStorage.setItem('test', 1);
// Main.jsx
alert(localStorage.getItem("test"));

💡 localStorage 저장 값 확인 하는 방법
개발자 도구 > Application > Lcal Storage

오리진(domain/port/protocol)만 같다면 url 경로는 달라도 동일한 결과를 볼 수 있다.
localStorage는 동일한 오리진을 가진 모든 창에서 공유되기 때문이다. 따라서 한 창에 데이터를 설정하면 다른 창에서 변동 사항을 볼 수 있다.

일반 객체처럼 사용하기 (추천하지 않음)

localStorage의 키를 얻거나 설정할 때, 아래처럼 일반 객체와 유사한 방법을 사용할 수 있다.

// 키 설정하기
localStorage.test = 2;

// 키 얻기
alert( localStorage.test ); // 2

// 키 삭제하기
delete localStorage.test;

이런 방법이 지원되긴 하지만 추천하지 않습니다.
1. 사용자는 lengthtoString, localStorage의 내장 메서드를 키로 설정할 수 있다. 이렇게 되면 getItem, setItem은 정상 작동해도, 일반 객체처럼 다룰 때 에러가 발생할 수 있다.

    let key = 'length';
    localStorage[key] = 5; // TypeError: Cannot assign to read only property 'length'...
  1. 데이터를 수정하면 storage 이벤트가 발생하는데, 이 이벤트는 localStorage를 객체처럼 접근할 땐 일어나지 않는다.

키 순회하기

localStorage는 key를 사용해 값을 얻고, 설정하고, 삭제할 수 있다.
키나 값 전체는 어떻게 얻을 수 있을까?
스토리지 객체는 반복 가능한 객체가 아니다. 대신 배열처럼 다루면 전체 key-value를 얻을 수 있다.

for(let i=0; i<localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(`${key}: ${localStorage.getItem(key)}`);
}

일반 객체를 다룰 때처럼 for key in localStorage 반복문을 사용해도 전체 키-값을 얻을 수 있습니다.
하지만 이 방법을 사용하면 필요하지 않은 내장 필드까지 출력된다 (??? 이게 무슨 소리지)

// 좋지 않은 방법
for(let key in localStorage) {
  alert(key); // getItem, setItem 같은 내장 필드까지 출력됩니다.
}

for key in localStorage 반복문을 사용하려면 hasOwnProperty를 이용해 프로토타입????에서 상속받은 필드를 골라내야 한다.

for(let key in localStorage) {
  if (!localStorage.hasOwnProperty(key)) {
    continue; // setItem, getItem 등의 키를 건너뜁니다.
  }
  alert(`${key}: ${localStorage.getItem(key)}`);
}

아니면 아래처럼 Object.keys로 '자기 자신’의 키를 받아온 다음 순회하는 방법을 사용할 수도 있다.

let keys = Object.keys(localStorage);
for(let key of keys) {
  alert(`${key}: ${localStorage.getItem(key)}`);
}

Object.keys는 해당 객체에서 정의한 키만 반환하고 프로토타입에서 상속받은 키는 무시하기 때문

문자열만 사용

숫자나 객체 등 다른 자료형을 사용하게 되면 문자열로 자동 변환된다.

localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]

JSON을 사용하면 객체처럼 쓸 수 있다.

localStorage.user = JSON.stringify({name: "John"});

let user = JSON.parse( localStorage.user );
alert( user.name ); // John

디버깅 등의 목적으로 스토리지 객체 전체를 문자열로 변환하는 것도 가능하다.

// 보기 좋도록 JSON.stringify에 서식 옵션을 추가했습니다.
alert( JSON.stringify(localStorage, null, 2) );

SessionStorage

  • sessionStorage의 데이터는 페이지 세션이 끝날 때 제거된다.
    - 브라우저가 종료되면 데이터도 같이 지워진다. (브라우저가 지워지면 SessionStorage도 삭제된다.)
    - 데이터가 지속적으로 보관되지 않는다. 브라우저 기반 세션 쿠키와 성질이 비슷하다. 현재 페이지가 브라우징되고 있는 브라우저 컨텍스트 내에서만 데이터가 유지된다.
    데이터의 지속성과 액세스 범위에 특수한 제한이 존재한다.
    Windows 전역 객체인 sessionStorage라는 컬렉션을 통해 저장과 조회가 이루어진다.
    도메인이 별도로 생성된다. 같은 사이트 같은 도메인이라 할지라도 브라우저가 다르면 서로 다른 영역이 된다. 브라우저 컨텍스트가 다르기 때문이다.
    탭 브라우징이나 브라우저를 하나 더 실행해서 같은 페이지를 실행했을 때, 이 두 페이지의 SessionStorage는 각각 별개의 영역으로 서로 침범하지 못한다는 의미이다. 이는 도메인만 같으면 전역적으로 공유 가능한 LocalStorage와 구분되는 특징이다.
    localStorage에 비해 자주 사용되진 않는다.
    제공하는 프로퍼티와 메서드는 같지만, 훨씬 제한적이다.
  • sessionStorage는 현재 떠 있는 탭 내에서만 유지된다.
    • 같은 페이지라도 다른 탭에 있으면 다른 곳에 저장되기 때문이다.
    • 하나의 탭에 여러 개의 iframe이 있는 경우엔 동일한 오리진에서 왔다고 취급되기 때문에 sessionStorage가 공유된다.
  • 페이지를 새로 고침할 때 sessionStorage에 저장된 데이터는 사라지지 않는다. 하지만 탭을 닫고 새로 열 때는 사라진다.
sessionStorage.setItem('test', 1);
alert( sessionStorage.getItem('test') ); // 새로 고침 후: 1

페이지를 새로 고침 하면 데이터가 여전히 남아있는 것을 확인할 수 있다.
하지만 다른 탭에서 본 페이지를 열고 위 예시만 실행해보면 null이 반환된다. (???? 계속 있는데…?)
이렇게 sessionStorage는 오리진뿐만 아니라 브라우저 탭에도 종속되어 있다. 이런 제약 때문에 sesstionStorage는 잘 사용되지않는다.

결론

웹 스토리지 객체(web storage object)의 보안은 서로 다른 도메인의 데이터 침범을 막고는 있지만 클라이언트, 즉 사용자를 막고 있지는 않다. 클라이언트는 얼마든지 저장된 값을 임의로 수정이 가능하다. 따라서 개발자는 사용자에 의한 임의 변경에 항상 예의 주시하고 방어 코드의 작성을 잊지 말아야한다.

profile
프론트엔드 개발자 가보자고~!!

0개의 댓글