[Network] #23 HTTP 기반 기술 (쿠키, 웹 스토리지, 콘텐츠 협상과 표현)
[혼자 공부하는 네트워크↗️], 컴퓨터 네트워킹: 하향식 접근 (제8판)을 바탕으로 정리한 글입니다.
- HTTP의 무상태(Stateless)와 비연결성 (Connectionless)특성으로 인해 서버는 클라이언트의 상태를 알 수 없다는 문제가 있다.
- 따라서 클라이언트의 상태를 알기 위해 쿠키, 세션, 토큰을 사용한다.
- 이번 포스팅에서는 HTTP 기반 기술에 대해서 학습해보자.
1. 쿠키
1.1 HTTP 프로토콜의 특성
쿠키와 세션은 HTTP 프로토콜의 특성을 보완하기 위해서 사용한다.
HTTP 특성 | 서명 |
---|---|
Connectionless (비연결지향) | 클라이언트와 서버가 요청을 주고받으면 연결을 끊어버린다. |
stateless (무상태성) | - 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는다. - 따라서 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다. |
HTTP의 2가지 특성인 Connectionless 과 stateless 로 인해 서버는 클라이언트의 상태를 알 수 없다는 문제가 있다.
- 예를들어 클라이언트의 상태를 서버가 알지 못한다면 페이지를 이동할 때마다 로그인을 다시 해야 할 것이다.
- 따라서 클라이언트의 상태를 알기 위해 (인증) 쿠키와 세션을 사용한다.
1.1 쿠키란?
서버에서 생성되어 클라이언트(브라우저)에 저장되는 텍스트 파일을 말한다. key-value 형태로 저장된다.
- 서버는
Set-Cookie
헤더를 통해 클라이언트에 쿠키를 전달한다. (응답) - 클라이언트는 쿠키를 저장하고
Cookie
헤더로 서버에 다시 전달한다. - 쿠키는 클라이언트 측에서 관리되며, 사용자의 컴퓨터에 있는 파일 시스템이나 메모리에 저장된다.
브라우저에서 쿠키를 직접 확인해보자
- 쿠키는 브라우저에서 저장되고 관리
- 크롬 브라우저에서 개발자 도구를 열고, [Application] - [Storage] - [Cookies]
- 아래와 같이 쿠키에는 다양한 속성들이 있는 것을 확인할 수 있다.
1.2 쿠키 인증 과정
- 클라이언트가 서버에 로그인 요청을 보낸다.
- 서버는 사용자의 로그인 상태나 관련 정보를 담은 쿠키를 생성하고, 이를 HTTP 응답 헤더의
Set-Cookie
필드에 포함하여 클라이언트로 전송한다. - 응답을 받은 브라우저(클라이언트)는 응답에 포함된
Set-Cookie
정보를 웹 브라우저 내부 쿠키 저장소에 자동으로 저장한다.- 저장된 쿠키정보는 [ 개발자도구 → 애플리케이션 → 저장용량 → 쿠키 ] 에서 확인 가능
- 저장된 쿠키정보는 [ 개발자도구 → 애플리케이션 → 저장용량 → 쿠키 ] 에서 확인 가능
- 로그인 이후 클라이언트의 PC에 해당 쿠키가 있는 경우, 브라우저에 저장되어 있는 쿠키는 자동으로 서버에 보내진다. (모든 요청에 쿠키 정보 자동 포함)
- 단, 동일한 Origin 또는 CORS를 허용하는 Origin에만 쿠키를 보낸다. (e.g., 유튜브 서버에서 받은 쿠키는 유튜브 이용 시에만 주고 받을 수 있다.)
- 이전 상태 정보를 변경할 필요가 있을 때 웹 서버는 HTTP 헤더에 “Set-Cookie”를 포함시켜 클라이언트에게 전송하고, 브라우저는 이 응답을 받아 쿠키를 자동으로 업데이트한다.
1.3 Origin과 CORS
Origin 이란?
origin(출처) 이란 protocol + host + port 를 의미한다.
CORS 정책
- Cross Origin Resource Sharing(CORS)는 다른 origin(출처) 에 리소스 요청하는 것을 허용하는 정책을 말한다.
- 쿠키는 동일한 도메인/서브도메인에서만 자동 전송. 다른 도메인으로는 전송되지 않는다. (e.g., example.com의 쿠키는 sub.example.com에서는 접근 가능하지만, anotherdomain.com에서는 불가능.)
- 쿠키 보안
- 쿠키의 Secure, HttpOnly, SameSite 속성을 활용하여 보안 위험을 줄일 수 있다.
- 민감한 정보는 쿠키에 저장하지 말고, 대신 세션 토큰이나 서버 측 세션 저장소를 활용해야 한다.
1.4 쿠키의 보안 설정
Secure
- 쿠키는 http, https를 구분하지 않고 전송한다.
- Secure를 적용하면 https인 경우에만 전송하도록 할 수 있다.
HttpOnly
- 자바스크립트에서 쿠키 접근 차단 → document.cookie로 읽을 수 없음
- HTTP 요청/응답에만 쿠키 사용하도록 제한 → XSS 공격 방지
SameSite
- 요청 도메인과 쿠키 도메인이 같을 때만 쿠키 전송 → XSRF 공격 방지
- 값 종류
- Strict: 요청 도메인이 다르면 쿠키 차단.
- Lax: 안전한 요청(GET)에서만 쿠키 전송.
- None: 제한 없이 모든 요청에서 쿠키 전송.
1.5 쿠키 특징
- 사용처
- 사용자 로그인 세션 관리
- 광고 정보 트래킹
- 사용자 맞춤형 서비스 제공
- 쿠키 정보는 항상 서버에 전송된다.
- 네트워크 트래픽 추가 유발하므로, 최소한의 정보만 사용해야 한다. (세션 id, 인증 토큰)
- 서버에 전송하지 않고 웹 브라우저 내부에 데이터를 저장하고 싶으면, 웹 브라우저를 사용해야 한다.
- 쿠키 한계
- 쿠키의 대표적인 한계는 보안이다.
- 쿠키 정보는 쉽게 노출되거나 조작될 수 있다.
- ⚠️ 보안에 민감한 데이터는 저장하면 안된다. (주민번호, 신용카드 번호 등)
- 쿠키는 모든 요청에 쿠키를 자동으로 포함한다.
- 따라서 이를 제약하기 위해 유효 기간을 설정해줘야한다.
1.6 쿠키의 생명주기
쿠키의 유효 기간은 설정에 따라 다르다. 별도로 삭제처리하거나 유효기간이 만료되지 않는 이상 서버와 통신할 때 자동으로 주고 받게 된다.
- 만료일 설정 (Expires)
Set-Cookie: expires=Sat, 26-Dec-2020
04:39:21 GMT- 해당 날짜 이후 쿠키 자동 삭제
- 수명 설정 (Max-Age)
Set-Cookie: max-age=3600
→ 3600초(1시간) 동안 유지.- max-age=0 또는 음수 → 즉시 삭제
- 세션 쿠키
- 만료일이 없으면 브라우저 종료 시 삭제된다.
- 영속 쿠키
- 만료 날짜를 입력하면 해당 날짜까지 유지된다.
💡 저장된 쿠키는 클라이언트 로컬 PC(하드 드라이브에 텍스트 파일)에 저장되며, 각각의 쿠키는 이름, 값, 만료 날짜/시간, 도메인 등의 속성을 가진다.
1.6.1 세션 쿠키 (Session Cookie)
유효기간
- 클라이언트가 서버에 접속하는 동안, 즉 세션이 유지되는 동안에만 저장되며, 웹 브라우저를 닫으면 자동으로 삭제된다.
- 클라이언트와 서버 간의 세션 연결을 유지하는 데 사용된다.
저장 위치
웹 브라우저의 메모리에서 저장
사용 예시
로그인 세션이나 쇼핑몰 장바구니와 같이, 사용자가 사이트를 탐색하는 동안만 필요한 정보를 저장하는 데 사용된다.
설정
서버에서 쿠키를 설정할 때 만료 시간을 지정하지 않으면, 자동으로 세션 쿠키가 된다.
1.6.2 영구 쿠키 (Persistent Cookie)
유효기간
명시된 만료 시간 또는 유효 기간까지 유지된다. 만료 시간은 Set-Cookie 헤더에서 Expires 또는 Max-Age 속성을 사용해 설정할 수 있다.
저장 위치
사용자의 하드디스크에 저장
사용 예시
- 사용자의 로그인 상태를 유지
- 사용자의 선호 설정(예: 언어 설정)을 기억
- “오늘 이 창 다시 보지 않기” 팝업창 설정 기억
// 쿠키가 7일(604800초) 동안 유지된다는 의미
Set-Cookie: username=JohnDoe; Max-Age=604800; Path=/
1.7 쿠키의 여러 속성
1.7.1 Domain
쿠키는 도메인 (Domain)을 지정하여 쿠키가 접근 가능한 도메인 범위를 설정할 수 있다. (e.g., domain=example.org)
- 쿠키가 사용할 수 있는 도메인 네임을 제한하기 위한 속성이 Domain이다.
- 응답 메시지 속 Set-Cookie 헤더의 “domain” 속성으로 정한다
① 명시적 도메인 지정
예를 들어, domain=example.org로 설정하면, example.org와 그 서브 도메인(e.g., dev.example.org, shop.example.org)에서도 쿠키를 사용할 수 있다.
② 도메인 생략 시
- 쿠키는 현재 도메인(example.org)에서만 접근 가능하며, 서브 도메인에서는 접근할 수 없다.
- e.g., example.org에서 생성한 쿠키는 dev.example.org에서는 접근 불가.
1.7.2 Path
같은 도메인이라도 쿠키를 구분하여 사용하고 싶을 경우 사용한다.
- 예를 들어,
www.example/lectures
를 포함한 하위 경로에서 사용하고자 하는 쿠키와www.example.com/books
를 포함한 하위 경로에서 사용하고자 하는 쿠키를 구분하고 싶을 경우 사용한다. - 만약
path=/home
이면, 이 경로를 포함한 하위 경로에서만 쿠키를 접근할 수 있으며, 일반적으로path=/
루트로 지정한다. - e.g.,
path=/home
→ 접근 가능/home
→ 접근 가능/home/level1/level2
→ 접근 가능/hello
→ 접근 불가
1.7.3 Expires / Max-Age
쿠키 유효 기간과 관련한 속성
- Expires 속성을 통해 쿠키 만료 시점 지정
- Max-Age 속성을 통해 초 단위 유효 기간 지정
1.8 세션 인증
쿠키를 활용하는 인증 기술이 세션 인증이다.
- HTTP는 스테이트리스 프로토콜이다.
- 따라서, 같은 클라이언트가 서버에 여러 번 요청을 보낸다고 해도, 기본적으로 서버는 모든 요청들을 별개의 요청으로 간주한다.
클라이언트가 서버에 요청 메시지를 보낼 때마다 (아이디, 비밀번호와 같은) 인증 정보를 보내고 번거로운 인증 과정을 거쳐야 하는 것일까?
-> 쿠키를 사용해서 인증을 구현한다면 그럴 필요가 없다.
세션 아이디(session id)와 세션 인증(session authentication)
- 클라이언트는 서버에게 (아이디, 비밀번호와) 같은 인증 정보를 전송
- 인증 정보가 올바르다면, 서버는 세션 아이디를 생성해 클라이언트에게 전송
- 서버는 생성한 세션 아이디를 DB 등에 저장
- 클라이언트는 추후 요청을 보낼 때 쿠키 내에 세션 아이디를 포함하여 전송
- 서버는 쿠키 속 세션 아이디와 저장된 세션 아이디를 비교하여 클라이언트 식별
➡️ 요청을 보낼 때마다 번거로운 인증 과정을 거칠 필요가 없다.
2. 쿠키와 유사한 웹 스토리지
클라이언트에 데이터를 저장할 수 있도록 HTML5부터 새롭게 지원하는 저장소이다.
- 웹 스토리지는 웹 브라우저 내에 저장된다.
- 쿠키는 약 4KB까지 밖에 저장 공간을 이용하지 못하는 반면에 웹 스토리지는 약 5MB까지 저장 공간을 이용할 수 있다.
- 웹스토리지는 쿠키와 달리 서버로 데이터를 전송하지 않고, 클라이언트 측에서 데이터를 저장하므로 서버에 부담이 가지 않는다.
- 웹 스토리지는 로컬 스토리지, 세션 스토리지로 분류할 수 있으며 가장 큰 차이점은 데이터의 영구성에 있다.
- 로컬 스토리지와 세션 스토리지는 window 객체의 프로퍼티로서 존재하며, 같은 Storage 객체를 상속하기 때문에 동일한 메소드들을 가진다.
2.1 로컬 스토리지
로컬 스토리지에 저장된 데이터는 사용자가 직접 삭제하지 않는 한 영구적으로 저장된다.
- 영구 저장: 로컬 스토리지에 저장된 데이터는 브라우저를 닫아도 사용자의 컴퓨터에 영구적으로 저장된다.
- 도메인 별로 저장: 로컬 스토리지는 도메인(웹사이트) 단위로 데이터를 저장한다. 서로 다른 브라우저 탭이라도 동일한 도메인이라면 동일한 로컬 스토리지를 사용한다.
- 자동 로그인과 같은 지속적으로 필요한 정보를 저장하기 좋다.
2.2 세션 스토리지
세션 스토리지는 로컬 스토리지와 유사한 웹 스토리지 기술이지만, 주로 세션 동안만 데이터를 저장하는 데 사용된다.
-
세션은 사용자가 웹사이트에 접속한 후 브라우저를 닫을 때까지의 기간을 의미한다.
- 세션 동안만 저장: 세션 스토리지에 저장된 데이터는 세션 동안만 유지되어 브라우저를 닫을 때 저장된 데이터가 삭제된다.
- 도메인 별로 저장: 로컬 스토리지와 마찬가지로, 세션 스토리지도 도메인 단위로 데이터를 저장한다.
- 일회성 로그인 등 잠시 동안 필요한 정보를 저장하기에 좋다.
개발자 도구를 활용해 로컬 스토리지와 세션 스토리지를 확인할 수 있다.
2.3 웹 스토리지 API
웹 스토리지는 기본적으로 키(key)와 값(value)으로 이루어진 데이터를 저장할 수 있다.
웹 스토리지 API 주요 메서드
메서드 | 설명 |
---|---|
setItem(key, value) | 지정된 키와 값을 스토리지에 저장한다. |
getItem(key) | 지정된 키에 해당하는 값을 스토리지에서 가져온다, 키가 존재하지 않을 경우 null 반환 |
removeItem(key) | 지정된 키에 해당하는 값을 스토리지에서 제거한다. |
clear() | 스토리지에 저장된 모든 키-값 쌍을 제거하여 스토리지를 비운다. |
length | 스토리지에 저장된 키-값 쌍의 개수를 반환한다. |
key(index) | 정된 인덱스에 해당하는 키를 반환한다. |
아래처럼 웹 스토리지 API를 사용하면 클라이언트 측에서 간단한 데이터 저장과 관리를 쉽게 할 수 있다.
// 로컬 스토리지에 데이터 저장
localStorage.setItem("name", "sieun");
localStorage.setItem("age", "22");
// 세션 스토리지에서 데이터 읽기
const name = sessionStorage.getItem("name");
console.log(name); // "sieun"
// 로컬 스토리지에서 데이터 제거
localStorage.removeItem("age");
// 스토리지 비우기
sessionStorage.clear();
3. 콘텐츠 협상과 표현
3.1 콘텐츠 협상이란?
HTTP의 특성을 다시 확인해보자.
- 클라이언트는 서버에 자원을 요청하고, 서버는 요청받은 자원을 응답한다.
- 자원은 URI(URL)로 특정 가능하다.
HTTP는 위와 같은 특성을 가지고 있음에도, 왜 같은 URL에 대해 같은 요청을 보냈는데 다른 응답을 받을까?
- 한국에서 접속하거나 한국어 계정으로 특정 URL에 접속하면 한국어로 된 웹 페이지
-
다른 지역에서 접속하거나 영어 계정으로 같은 URL에 접속하면 영어로 된 웹 페이지
바로 콘텐츠 협상 때문이다.
- 콘텐츠 협상이란, 클라이언트가 선호하는 표현을 요청하는 기능으로, 클라이언트가 서버에 요청을 보내면서 자신이 원하는 콘텐츠 형식, 언어, 압축 방식 등을 명시할 수 있다. (콘텐츠 네고이에이션)
- 서버는 클라이언트가 제시한 정보를 바탕으로 적절한 응답을 선택하여 보내게 된다.
- 이 과정은 HTTP 헤더를 통해 이루어지며, 협상 헤더는 요청 시에만 사용된다.
- 같은 URI로 식별 가능한 HTML 문서라 해도 영어로 요청하면 영어로 된 형태를 제공, 한국어로 요청하면 한국어로 된 형태를 제공한다.
- 여기서 자원의 형태를 표현이라고 부른다.
3.2 자원의 표현
송수신 가능한 자원의 형태를 의미한다.
즉, 콘텐츠 협상은 클라이언트에게 가장 적합한 자원의 표현을 제공하는 메커니즘이다.
3.3 콘텐츠 협상 관련 HTTP 헤더
헤더 | 설명 |
---|---|
Accept 헤더 | 선호하는 미디어 타입 |
Accept-Language | 선호하는 언어 |
Accept-Charset 및 Accept-Encoding | 선호하는 문자 인코딩과 압축 방식 |
e.g., 클라이언트가 선호하는 언어가 한국어 및 클라이언트가 HTML 문서 타입을 선호
3.4 협상과 우선순위
선호도에 우선순위를 반영할 수 있다.
- 클라이언트가 여러 개의 미디어 타입, 언어, 압축 방식을 선호할 경우 클라이언트는 선호하는 표현의 우선순위를 부여할 수 있다.
-
우선 순위는 콘텐츠 협상 관련 헤더의 q값으로 표현한다. (q는 Quality Value의 약자)
- 0 ~ 1, 값이 클수록 우선순위가 높음
- 생략되었을 경우에는 1을 의미
-
아래는 클라이언트가 한국어(ko-KR, ko), 영어(en-US, en)순으로 선호하고, HTML, XML, 일반 텍스트 순으로 선호한다는 의미이다.
구체적일수록 우선순위가 높다.
Accept: text/*, text/plain, text/plain;format=flowed, */*
- text/plain;format=flowed
- text/plain
- text/*
- */
구체적인 것을 기준으로 미디어 타입을 맞춘다.
` Accept: text/;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */;q=0.5`
Media Type | Quality Value |
---|---|
text/html;level=1 | 1 |
text/html | 0.7 |
text/plain | 0.3 |
image/jpeg | 0.5 |
text/html;level=2 | 0.4 |
text/html;level=3 | 0.7 |
댓글남기기