콘텐츠로 건너뛰기
Home » Blog » HTTP, 로컬 스토리지, 세션 스토리지, 쿠키

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

HTTP 헤더

  • 사용자가 HTTP 요청을 하게 되면 헤더와 바디를 주고받는다.
  • Resoponse탭에 있는 컨텐츠 = body / Headers에 있는 컨텐츠 = Header
  • 서버에서 설정하는 헤더 = 응답 헤더 / 클라이언트에서 설정한 헤더 = 요청 헤더

일반 헤더

  • 요청한 URL, 요청 메서드, 해당 자원을 요청할 때 해당 자원의 출처를 나타내는 URL을 노출시킬지 말지를 정하는 보안 정도가 설정되어있는 Referrer Policy 등이 들어간다.

요청 헤더

  • 클라언트가 서버에 요청할 때 클라이언트가 설정하는 또는 자동으로 설정되는 헤더
  • 메서드, 클라이언트의 OS, 브라우저 정보 등이 담긴다.

응답 헤더

  • 서버가 클라이언트에게 응답을 보낼 때 설정하는 또는 자동으로 설정되는 헤더
  • 서버의 소프트웨어 정보 등이 담긴다.
  • ex) nginx를 프록시 서버로 두었다면 해당 정보가 표기된다.
    • 그러나 대부분의 서버는 일반적으로 해커가 서버에서 어떤 소프트웨어가 사용되고 있는지 알기 어렵게 하기 위해 서버 정보를 숨긴다.

헤더의 유연성

  • HTTP 헤더는 굉장히 유연하게 설계가 되어 있어 커스텀하게 만들 수 있다.
  • 그러나 보통은 지정된 key값에 value를 담아서 헤더를 설정한다.

HTTP 1.0 ~ 3

  • HTTP 요청이라는 기술은 1.0부터 시작해 지금은 3까지 많은 발전을 거듭해왔다.

HTTP/1.0

  • 수명이 짧은 연결
  • HTTP 요청은 자체 요청에서 완료된다.
  • 각 HTTP 요청 당 TCP 핸드셰이크가 발생되며 기본적으로 한 연결 당 하나의 요청을 처리하도록 설계
  • 한번 연결할 때 마다 TCP연결을 계속해야 하니 RTT가 늘어나는 문제점이 있었다.
    • RTT(Round Trip Time : 왕복 지연 시간)
    • 신호를 전송하고 해당 신호의 수신확인에 걸린 시간을 더한 값이자 어떤 메세지가 두 장치 사이를 왕복하는 데 걸린 시간

HTTP/1.1

  • HTTP/1.1은 HTTP/1.0의 단점을 보완한 프로토콜이다. 1.0과는 크게 3가지의 차이점이 있다.

1. keep-alive default

  • 매번 데이터를 요청할 때마다 TCP 연결을 하는게 아닌 한 번 연결해놓고 계속해서 데이터를 받을 수 있게 만들었다.
  • 이는 keep-alive 옵션을 기본옵션으로 하면서 가능해졌다.

2. 호스트 헤더

  • HTTP/1.0은 서버가 하나의 호스트만 가진다고 가정하기 때문에 HTTP/1.0은 헤더에 호스트를 포함하지 않았다.
  • 이 때문에 HTTP/1.0은 하나의 IP에 하나의 호스트만 가질 수 있었다.
  • 그러나 사실 서버는 여러 개의 호스트를 가질 수 있으며 이런 유연성을 위해 HTTP/1.1은 헤더에 특정 호스트를 포함할 수 있게 변경되었으며 항상 호스트를 포함해서 요청하도록 바뀌었다.

3. 대역폭 최적화

  • HTTP/1.0의 경우 어떠한 파일을 다운로드 받다가 연결이 끊기면 다시 다운로드 받는 것이 불가능했다.
  • 이를 다시 다운로드 받을 수 있게 바뀌었다.
  • Range:bytes=5000- 라는 헤더를 추가 → 다운로드 재개 요청

요청을 줄이기 위한 기술

  • HTTP/1.1로 발전했음에도 불구하고 서버 요청할 때마다 RTT는 계쏙해서 증가하기에 요청을 줄이기 위한 여러 기술들이 있었다.
  • 이미지 스프라이트(image sprite), 코드 압축, Base64 인코딩 등
  • HTTP버전이 올라간 뒤에도 이러한 기술들을 같이 쓰고는 한다.

이미지 스프라이트

  • 수 많은 이미지를 하나의 이미지로 만들어 하나의 이미지만 다운받아놓고 이를 통해 수 많은 이미지를 다운받는 듯한 효과를 내는 것

코드 압축

  • 띄어쓰기, 개행문자 등을 줄여서 코드를 짧게 만드는 것 → 이래서 CSS 파일이 한 줄에 있던것이었나..?

이미지 Base64 인코딩

  • 이미지 파일을 64진법으로 이루어진 문자열로 인코딩해서 이미지 서버에 대한 HTTP 요청을 할 필요가 없이 만드는 것
  • 그러나 Base64 인코딩을 할 경우 파일 크기가 37퍼센트 더 커지는 단점이 있었다.

HTTP/1.1의 고질적인 문제 : HOL

  • HOL(Head Of Line Blocking)과 무거운 헤더를 가지는 문제점이 있었고 이를 해결하지 못했다.
    • HOL : 네트워크에서 같은 큐에 있는 패킷이 그 첫번째 패킷에 의해 지연될 때 발생하는 성능 저하 현상

HTTP/2

  • 2009년 구글은 HTTP/1.1의 한계를 극복하기 위해 SPDY 프로토콜을 개발했다.
  • 이 후 2015년, SPDY를 기반으로 하는 HTTP/2 프로토콜을 만들었다.

바이너리 포맷 계층

  • 애플리케이션 계층과 전송 계층 사이에 바이너리 포맷 계층을 추가한다.
  • HTTP 1.0은 일반 텍스트 메세지를 전송하고 줄바꿈으로 데이터를 나눴다면 HTTP 2.0은 0과 1로 이루어진 바이너리 데이터로 변경되었고 더 작은 메세지가 프레임으로 캡슐화 되어서 전송된다.

멀티플렉싱

  • 단일 TCP 연결의 여러 스트림에서 여러 HTTP 요청과 응답을 비동기적으로 보낼 수 있다. 이를 통해 HOL을 해결한다.
  • HTTP/1.1에서는 병렬요청을 하려면 다중 TCP연결을 통해서 하고 일반적으로는 TCP연결 하나 당 병렬 요청은 불가능했다.
  • 이를 HTTP/2.0에서는 리소스를 작은 프레임으로 나누고 이를 스트림으로 프레임을 전달한다.
  • 각가의 프레임은 스트림ID, 해당 chunk의 크기를 나타내는 프레임이 추가되었기때문에 작게 나눠서 다운로드가 되더라도 결과적으로 응답데이터에서는 올바른 순서로 재조립할 수 있게 된다.

서버 푸시

  • 서버가 리소스를 클라이언트에 푸시
  • 요청된 html파일과 함께 다른 개체를 별도로 보낼 수 있다.
  • 만약 요청한 html에 css가 포함되어 있다면 별도 요청없이 css를 같이 보낼 수 있다.

헤더 압축

  • HTTP/1.1에서는 무거운 헤더가 있었지만 이를 허프만 인코딩 압축 방법 등으로 압축시킨다.
  • 똑같은 서버에서 2개의 이미지를 준다고 했을 때 중복되는 헤더는 제외한 채 보내고 해당 공통 필드로 헤더를 재구성하며 중복되지 않은 헤더값은 허프만 인코딩 압축 방법으로 압축해 전송한다.

우선순위

  • 서버에서 원하는 순서대로 우선순위를 정해 리소스를 전달할 수 있다.

HTTP/3

  • HTTP/2는 여전히 TCP를 사용하기 때문에 초기 연결에 대한 RTT로 인한 지연시간이라는 문제점이 있었고 이를 해결한 버전
  • QUIC(Quick UDP Internet Connections)이라는 계층 위에서 돌아간다.
  • TCP 기반이 아닌 UDP 기반으로 돌아간다.
  • HTTP/2에서 장점이었던 멀티플렉싱 등을 가지고 있다.
  • 초기 연결설정 시 지연시간이 감소하는 대표적 특성을 가지고 있다.
  • TCP의 경우 3 – RTT가 필요했었으나, QUIC의 경우 1 – RTT만 필요하다.
  • HTTP/2나 HTTP/3 는 HTTPS 위에서 돌아가는데 TLS로 암호와통신을 구축할 때의 핸드셰이크를 활용한다.
  • 이를 기반으로 1 – RTT만에 연결을 성립할 수 있다.
  • 전송된 패킷이 손실 되었다면 수신측에서 에러를 검출하고 수정하는 방식이며 열악한 네트워크 환경에서도 낮은 패킷 손실률을 자랑하는 순방향 오류 수정 메커니즘(FEC)이라는 특징을 가진다.

HTTP와 TLS

암호화

  • 암호화는 승인된 당사자만 정보를 이해할 수 있도록 데이터를 “스크램블”하는 방법
  • 이를 복호화하려면 송신자와 수신자가 서로 동의한 “키”가 필요하다.
  • 이를 만들기 위해 키가 쓰이기도 한다.
  • plaintext + key = ciphertext
  • ciphertext = plaintext + key
  • ex) DES, AES

스크램블

  • 각 단어나 문자를 패턴에 따라 암호화하는 것이 아니라 무작위 방식으로 개별 데이터 비트를 섞는 것

대칭 암호화

  • 키를 하나만 사용하는 암호화 방법
  • 특정한 키로 암호화 한다고 가정해보면, 해독을 할 때에도 동일한 키로 해독하는 것

비대칭 암호화

  • 공개키 암호화라고도 불린다.
  • 두개의 다른키 (공개키, 개인키)로 데이터를 암호화하거나 서명하고 키 중 하나인 공개키를 누구나 사용할 수 있도록 하는 방법
  • 공개키로 암호화된 데이터는 개인키로만 복호화할 수 있게 한다.
  • RSA, DH(Diffe-Hellman)
  • HTTPS를 가능하게 하는 프로토콜인 TLS는 부분적으로 비대칭 암호화를 쓴다. (TLS는 대칭암호화도 쓴다)
    • HTTLS = HTTP + TLS

암호화의 필요성

  • 의도된 수신자 또는 송신자를 제외하고는 통신을 하이재킹하여 읽을 수 없게 한다.
  • 이를 통해 민감한 데이터를 유출을 방지하고 데이터의 무결성을 보장한다.

TLS


로컬 스토리지

  • 웹 스토리지 객체로 브라우저 내에 {key : value} 형태로 오리진에 종속되어 저장되는 데이터
    • 오리진이 같은 브라우저 내에서 공유된다.
  • 하나의 키에 오로지 하나의 값만 저장
  • 데이터는 사용자가 브라우저에서 수동으로 삭제하지 않는 한 평생 동안 로컬 저장소에 저장되며 만료 날짜가 없다.
  • 사용자가 창이나 탭을 닫아도, 컴퓨터를 종료해도 만료되지 않는다.
  • 최대 저장 용량은 5MB
  • 보통 사용자의 행위를 기억할 때, 로그인을 유지하기 위한 값 등으로 사용되며 로컬 스토리지 데이터는 자동으로 서버로 전송되지 않는다. (↔ 쿠키는 자동 전송된다)

사용법

  • 설정 : localStorage.setItem(key, value);
  • key에 해당하는 value가져오기 : localStorage.getItem(key);
  • 제거 : localStorage.removeItem(key);
  • 전체제거 : localStorage.clear();

로컬 스토리지와 오리진


세션 스토리지

  • 로컬 스토리지와 매우 유사
  • 세션 스토리지는 웹 스토리지 객체로 브라우저 내에 {key : value} 형태로 오리진에 종속되어 저장되는 데이터
    • 오리진이 같은 브라우저 내에서 공유된다.
  • 하나의 키에 오로지 하나의 값만 저장된다.
  • 최대 저장용량은 5MB 이내 → 여기까지 로컬 스토리지와 똑같다.
  • 사용자가 브라우저에서 탭을 닫으면 데이터는 만료된다.
  • 보통은 세션 스토리지보다는 로컬 스토리지를 많이 쓴다.

사용법

  • 설정 : sessionStorage.setItem(key, value);
  • 탐색 : sessionStorage.getItem(key);
  • 제거 : sessionStorage.removeItem(key);
  • 전체제거 : sessionStorage.clear();

쿠키

  • 쿠키는 브라우저에 저장된 데이터 조각
  • 클라이언트에서 먼저 설정할 수도 있고 서버에서 먼저 설정할 수 있으나 보통은 서버에서 먼저 설정해서 쿠키를 만드는게 일반적이다.
  • 서버에서 응답 헤더로 Set-Cookie로 설정해서 쿠키를 보내면 그 때 부터 클라이언트에서 요청헤더 Cookie에 설정되어 자동으로 서버에 전달되게 되고 브라우저에도 저장되게 된다.
    • HTTP 헤더를 통해 클라이언트 또는 서버가 HTTP 요청 또는 응답 할 때 추가 정보를 전달할 수 있다.
  • 쿠키는 클라이언트와 서버 둘 다 조작이 가능하지만 보통 서버에서 만료기한 등을 설정 및 컨트롤 한다.
  • 저장 용량은 최대 4KB까지 가능하다.
  • 보통 로그인, 장바구니, 사용자 커스터마이징, 사용자 행동분석(주로 개인화된 광고에 활용되는 것들)에 사용된다.

클라이언트에서도 설정 가능한 쿠키

  • 클라이언트에서 자바스크립트 – document.cookie를 통해 쿠키를 설정할 수 있고 보낼 때도 이런식으로 header – Cookie에 값을 정해서 보낼 수도 있다. (권장하지는 않는다)
    • 이러면 쿠키에 대한 제어권을 클라이언트에게 두게되는데 쿠키에는 보통 민감한 정보들이 담길 수 있기 때문에 이 제어권에 관한 것을 클라이언트가 아닌 서버에 두게 만들어야 한다.

세션 쿠키

  • Expire 또는 Max-Age 속성을 지정하지 않은 것
  • 브라우저가 종료되면 쿠키도 사라진다.

영구 쿠키

  • Expire 또는 Max-Age 속성을 지정해서 특정 날짜 또는 일정 기간이 지나면 삭제되게 만든 쿠키
  • 브라우저를 닫을 때 만료되지 않는다.

문법

  • Set-Cookie: <cookie-name>=<cookie-value>
  • Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
  • Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
  • Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
  • Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
  • Set-Cookie: <cookie-name>=<cookie-value>; Secure
  • Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
  • Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict

secure

  • https로만 쿠키를 주고받을 수 있게 하는 옵션
  • Chrome 52 이상 및 Firefox 52 이상을 포함한 일부 브라우저는 보안을 강화
    • 안전하지 않은 사이트(HTTP)가 Secrue 지시문으로 쿠키를 설정하는 것을 금지하기 위해 이 사양을 현재는 무시한다.

httponly

  • 공격자가 자바스크립트로 쿠키를 빼낼 수 없게 만든다. (document.cookie로 접근 불가)

samesite

  • 요청이 동일한 도메인에서 시작된 경우에만 쿠키가 애플리케이션으로 전송되도록 허용

쿠키의 secure 코딩

→ 쿠키 – 세션으로 로그인을 처리한다면 다음과 같은 시큐어 코딩을 해야한다.

  • 쿠키에 세션 ID를 담을 때 이 세션 ID 기반으로 클라이언트의 개인정보를 유추할 수 없게 해야 한다.
  • 자바스크립트로는 파악할 수 없게 http only 옵션을 걸어야 한다.
  • 일정시간의 세션 타임아웃을 걸어야 한다.

쿠키 허용 관련 알림창

  • 서비스 운용 시 쿠키를 사용한다면 쿠키 허용 관련 알림창을 만들어야 한다.
  • 방문기록을 추적할 때 쿠키가 사용되기 때문
  • 이는 사용자의 데이터 간접수집에 해당하며 거기에 해당하는 KISA 지침을 준수해야하기 때문이다.

로컬 스토리지, 세션 스토리지, 쿠키의 공통점과 차이점

공통점

  • 브라우저에 캐싱을 함으로써 서버에 대한 요청을 줄여 서버 부하를 방지할 수 있다.
  • 캐싱으로 인해 다운로드 하는 컨텐츠가 줄어들어 웹사이트의 컨텐츠를 더 빨리 다운로드가 가능하다.
  • 사이트 기본 설정 커스터마이징(색상, 글꼴 크기 등)을 저장하거나 로그인 상태를 유지할 때 사용될 수 있다.

차이점

쿠키로컬 스토리지세션 스토리지
최대저장용량4KB5MB5MB
브라우저 허용HTML4 + 5HTML 5HTML 5
접근 범위
만료 기한수동영구탭 닫으면 소멸
설정 주체클라이언트 + 서버클라이언트클라이언트
요청과 함께 서버에 자동 전송OXX