안녕하세요. IT 엘도라도 에 오신 것을 환영합니다.
글을 쓰는 것은 귀찮지만 다시 찾아보는 것은 더 귀찮습니다.
완전한 나만의 것으로 만들기 위해 지식을 차곡차곡 저장해 보아요.   포스팅 둘러보기 ▼

웹, 앱 (Web, Application)

[Web] 쿠키, 웹 스토리지 (로컬 스토리지, 세션 스토리지)

피그브라더 2020. 8. 4. 11:08

1. 쿠키 (Cookie)

  • 클라이언트가 서버에 방문한 정보를 클라이언트 단에 저장하는 작은 파일을 의미한다.
  • 클라이언트의 브라우저 메모리 혹은 하드디스크에 저장이 된다. (↔ 세션)
  • 매번 서버에 전송되므로 크기가 클 경우 서버에 부담이 갈 수 있다.
  • SameSite 옵션이 Strict가 아닌 경우, 다른 도메인에서 요청할 때도 자동 전송되는 위험성이 있다. (CSRF 취약)
  • 대략 4KB까지의 데이터를 저장할 수 있으며 유효 기간이 존재한다.
  • 대부분의 브라우저가 지원한다.

 

※ 다른 오리진(= 프로토콜 + 도메인 + 포트) or 다른 도메인에 대한 이슈

1. 브라우저의 CORS 정책은 다른 오리진에 대한 요청을 막음 :
브라우저는 다른 오리진에 요청을 보낼 때 요청의 Origin 헤더에 자신의 오리진을 실어 보낸다. 그리고 서버는 응답 시에 응답의 Access-Control-Allow-Origin 헤더에 허용되는 오리진들의 목록을 실어 보낸다. 그러면 브라우저는 이 두 헤더의 값을 비교하여 허용되는 오리진에 대한 요청일 경우에만 해당 응답을 채택한다. 따라서 백 엔드 서버에서 Access-Control-Allow-Origin 헤더를 설정해주지 않으면 CORS 요청은 막힐 것이다.

2. 다른 오리진에 대한 요청 시에는 쿠키를 전송 혹은 수신할 수 없음 :
브라우저가 다른 오리진에 요청을 보낼 때 별도의 설정을 해주지 않으면 쿠키를 보낼 수도 없고, 받을 수도 없다. 해당 설정은 요청을 보내는 방식에 따라 다르다. 만약 XMLHttpRequest, jQuery의 ajax, 또는 axios를 사용한다면 withCredentials 옵션을 true로 설정해줘야 하고, fetch API를 사용한다면 credentials 옵션을 include로 설정해줘야 한다. 그리고 서버에서도 응답 시에 응답의 Access-Control-Allow-Credentials 헤더 값을 true로 설정해줘야 하고, Access-Control-Allow-Origin 헤더 값에는 *를 사용하지 않아야 한다. 그래야 브라우저가 해당 응답을 채택할 수 있다. (참고)

3. JavaScript로 읽을 수 있는 쿠키의 범위 (HttpOnly 옵션이 false임을 가정) :
JavaScript에서 쿠키는 document.cookie를 통해 상위 도메인의 쿠키까지 읽을 수 있다. 예를 들어, sub.example.org에서는 sub.example.org의 쿠키뿐 아니라 example.org의 쿠키까지 읽을 수 있다. 따라서 상위 도메인이 같은 다른 하위 도메인들의 경우 서로의 쿠키를 읽을 수 없다. 예를 들어, sub1.example.org에서는 sub2.example.org의 쿠키를 읽을 수 없다. 이것이 가능하려면 해당 쿠키를 설정할 때 domain=example.org 옵션을 설정해줘야 한다. (참고)

4. 하위 도메인(sub.example.org)의 백 엔드 서버에서 응답 시에 쿠키를 설정해주는 방법 :
서버는 응답 시 쿠키의 domain 옵션을 명시적으로 설정해줄 수 있다(단, 자기 자신 혹은 자기 자신의 상위 도메인으로만 설정해줄 수 있으며, 그렇지 않으면 브라우저가 해당 쿠키를 무시). 설정해주지 않으면 기본값은 자기 자신이다. 예를 들어, sub.example.org의 백 엔드 서버가 응답 시 쿠키의 domain 옵션을 설정해주지 않으면 domain 옵션의 기본값은 sub.example.org로 설정된다. 하지만 domain 옵션의 값을 example.org로 명시적으로 설정해줄 수도 있고, 그러면 example.org에 해당하는 웹사이트에서도 해당 쿠키를 참조할 수 있게 된다. (참고)

5. 쿠키의 SameSite 옵션은 기본값이 Lax :
GET 등의 안전한 요청이 아닌 이상 동일한 사이트일 때만 해당 쿠키를 전송하도록 하는 옵션이다. 여기서 말하는 동일한 사이트란 1차 도메인과 2차 도메인의 조합을 의미한다. 즉, a.example.org와 b.example.org는 동일한 사이트이다. (참고)

 

2. 웹 스토리지 (Web Storage)

  • 클라이언트에 데이터를 저장할 수 있도록 HTML5부터 새롭게 지원하는 저장소이다.
  • 키(Key)와 값(Value)의 쌍 형태로 데이터를 저장한다.
  • 쿠키와 달리, 서버에 전송되지 않으므로 서버에 부담이 가지 않는다. (명시적으로만 전송 가능)
  • 쿠키와 달리, 필요한 경우에만 꺼내 쓰는 것이므로 자동 전송의 위험성이 없다. 다른 오리진에서 요청하는 경우에는, 꺼내 쓰고 싶어도 오리진 단위로 접근이 제한되는 특성 덕분에 값을 꺼내 쓸 수 없다. (CSRF 안전)
  • 쿠키와 달리, 대략 5MB까지의 데이터를 저장할 수 있으며 유효 기간이 존재하지 않는다.
  • HTML5를 지원하지 않는 브라우저에서는 사용할 수 없다.
  • 종류로는 로컬 스토리지(Local Storage)세션 스토리지(Session Storage)가 있다. 이들은 window 객체의 프로퍼티로서 존재하며, 같은 Storage 객체를 상속하기 때문에 동일한 메소드들을 가진다. 이 둘의 가장 큰 차이점은 데이터의 영구성이다.

 

3. 로컬 스토리지 (Local Storage)

  • window.localStorage 객체
  • 브라우저를 종료해도 유지되는 데이터로, 명시적으로 지우지 않는 한 영구적으로 저장된다.
  • 오리진(= 프로토콜 + 도메인 + 포트)별로 생성되며, 다른 오리진의 로컬 스토리지에는 접근이 불가능하다.
  • 서로 다른 브라우저 탭이라도 동일한 오리진이라면 동일한 로컬 스토리지를 사용한다.
  • 지속적으로 필요한 정보를 저장하기에 좋다. (ex. 자동 로그인 등)

 

4. 세션 스토리지 (Session Storage)

  • window.sessionStorage 객체
  • 세션 쿠키와 달리, 탭/윈도우 단위로 세션 스토리지가 생성된다.
  • 즉 window 객체와 동일한 유효 범위 및 생존 기간을 가지며, 탭/윈도우를 닫을 시 데이터가 삭제된다.
  • 또한 동일한 탭/윈도우라도 다른 오리진(= 프로토콜 + 도메인 + 포트)이라면 또 다른 세션 스토리지가 생성된다.
  • 서로 다른 세션 스토리지는 서로 영향을 주지 않으며 독립적으로 동작한다.
  • 윈도우 복제로 생성된 경우, 혹은 스크립트로 새 창을 연 경우 세션 스토리지가 복제되어 생성된다.
  • 잠시 동안 필요한 정보를 저장하기에 좋다. (ex. 입력 폼 저장, 일회성 로그인 등)

 

 

 

 

 

 

본 글은 아래 링크의 내용을 참고하여 학습한 내용을 나름대로 정리한 글임을 밝힙니다.

https://untitledtblog.tistory.com/47

https://androphil.tistory.com/524

https://developer.mozilla.org/ko/docs/Web/API/Window/sessionStorage