HTTP 헤더 (HTTP Body, 표현, 협상, 쿠키)

2022. 11. 8. 00:43CS/HTTP

HTTP Body

message body - RFC7230

 

 

  • 메시지 본문(message body)을 통해 표현 데이터 전달
  • 메시지 본문 = 페이로드(payload) 
  • 표현은 요청이나 응답에서 전달할 실제 데이터
  • 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
    • 데이터 유형(html, json), 데이터 길이, 압축 정보 등등
    • 전송, 응답 둘 다 사용

 

 

 

표현(Representation)

어떤 리소스가 있을 때 이게 html로 되어 있을 수도 있고 Json데이터 형식으로 되어 있을 수 있습니다.

여기에 표현이라는 용어를 접목해보자면, '나는 이 리소스를 html 표현으로 전달할 거야 / 저 리소스는 Json 표현으로 전달할거야' 라고 말할 수 있습니다.

  • Content-Type: 표현 데이터의 형식
  • Content-Encoding: 표현 데이터의 압축 방식
  • Content-Language: 표현 데이터의 자연 언어
  • Content-Length: 표현 데이터의 길이

 

(1) Content-Type

본문이 어떤 형식으로 되어있는지 알 수 있습니다.

예시)
text/html; charset=utf-8 
application/json
image/png

 

(2) Content-Encoding

표현 데이터를 압축하기 위해 사용합니다. 데이터를 전달하는 곳에서 압축 후 인코딩 헤더에 추가하면

전달받는 곳에서 확인 후 해당 정보를 참고해 압축을 해제합니다.

예시)
gzip
deflate
identity    ←  압축을 안 한다는 것

 

(3) Content-Language

활용)
사이트에 접속했을 시 난 한국어 유저인데 본문이 영어로 되어있다면 Content-Language를 참고해서
한국어 → 영어로 변환할 수 있는 작업을 추가적으로 할 수 있습니다.

예시)
ko
en

 

(4) Content-Length

바이트 단위입니다.

Transfer-Encoding(전송 코딩)을 사용하면 (안에 정보들이 다 들어있으므로) Content-Length를 사용하면 안 됩니다.

 

 

 

협상 헤더 (콘텐츠 네고시에이션)

클라이언트가 서버에 요청하는 방식으로 최대한 내(클라이언트)가 선호하는 표현으로 달라고 하는 것입니다.

물론 서버가 준비가 안 되어있는데 클라이언트가 원한다고 다 줄 수는 없겠지만, 최대한 고려해서 응답해줄 수 있습니다. 

(협상 헤더는 요청 시에만 사용 가능) 

  • Accept: 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
  • Accept-Language: 클라이언트가 선호하는 자연 언어

 

위에서 잠깐 활용 예시를 든 것에 살을 붙여본다면, 

A사이트는 기본으로 영어를 지원하지만 한국어도 지원하고 있는 상황에서 한국어를 쓰는 내가 접속을 했을 때

"A사이트 네가 한국어도 지원하고 있다면, 다른 언어 말고 한국어로 보내줘!"라고 요청할 수 있습니다.

 

하지만 이런 경우라면 어떨까요?

A사이트는 한국인 유저가 별로 없어서 기본으로 영어로 응답해주고 중국어, 스페인어, 독일어도 추가적으로 지원해주고 있습니다. 이때 제가 위와 같이 "한국어를 지원하고 있다면, 한국어로 응답해줘"라고 요청한다면 

A사이트는 어떤 언어로 응답해야 할까요?

 

 

이 경우 우선순위(Quality Values, q로 표기)를 적용하면 문제를 해결할 수 있습니다.

 

GET /event
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7

0 ~ 1로 표현하며 클수록 높은 우선순위이고 생략 시 1을 나타냅니다.

ko → en-US → en순으로 우선순위가 있다는 것을 한눈에 알 수 있게 되었습니다. 

 

 

 

쿠키

쿠키를 사용할 때 사용하는 2개의 헤더

  • Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
  • Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달

 

이 두줄에 대한 이해가 완전히 가지 않는다면 쿠키를 사용하지 않았을 경우를 살펴보면 쿠키에 대한 개념이 어느 정도 잡히실 것입니다.

 

쿠키를 사용하지 않을 경우)

A가 B사이트 접속해서 로그인을 하고 다시 해당 사이트로 돌아왔을 때 "안녕하세요, A님"이 아닌 "안녕하세요, 고객님"이라는 문구를 보게 되었습니다.

나는 분명 로그인을 했는데 실수로 서버에서 인식을 못할 것일까요?

 

아닙니다, 그 이유는 HTTP는 무상태(Stateless) 프로토콜이기 때문입니다. 클라이언트와 서버가 요청과 응답을 주고받으면 연결이 끊어지기에 서버는 이전 요청을 기억하지 못했던 것입니다.

 

 

그렇다고 해서 매번 클라이언트가 모든 요청에 사용자 정보를 넣어서 보내면 보안에도 문제가 있고 개발자도 이러한 부분을 다 넣어서 개발해야 하기 때문에 번거롭습니다.

 

 

이러한 문제점을 해결하기 위해 도입한 개념이 쿠키입니다.

 

로그인을 예로 들어 설명해보겠습니다. 웹 브라우저에서 서버로 user = A로 로그인 요청을 하면 

서버에서는 Set-Cookie : user = A라는 키 밸류 형태로 넣어 응답합니다.

그러면 웹 브라우저는 쿠키 저장소에 이를 저장합니다.(Cookie)

 

 

그 후 웹 브라우저는 서버에 요청을 보낼 때마다 쿠키 저장소에서 쿠키를 꺼내서 서버에 보냅니다.

 

 

 

여기까지를 정리해보자면,

  • 쿠키는 주로 사용자 로그인 세션 관리에 쓰입니다. 
  • 쿠키 정보는 항상 서버에 전송됩니다.
    • 네트워크 트래픽을 추가 유발하므로 최소한의 정보만 사용해야 합니다.(세션 id, 인증 토큰)
    • 만약 서버에 전송하지 않고 웹 브라우저 내부에 데이터를 저장하고 싶다면 웹 스토리지를 사용
  • 당연하게도 보안에 민감한 정보는 저장하면 안 됩니다.

 

 

 

여기에 추가적으로 쿠키는 생명주기 관리, 도메인 명시, 경로 지정, 보안 설정을 할 수 있습니다.

 

(1) 생명주기 관리

만료일 또는 만료 시간(second)을 지정할 수 있습니다. 지정한 시간이 지나면 쿠키가 삭제됩니다.

[표기]
만료일
Set-Cookie : expires =.....

만료시간 - 만약 0이나 음수를 지정하면 쿠키 삭제
Set-Cookie: max-age=...


[생명주기 관련 쿠키]
- 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료 시까지만 유지
- 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지

 

 

(2) 도메인 명시

만약 도메인을 명시한다면 명시한 문서 도메인과 서브 도메인까지 쿠키가 접근이 가능합니다.

도메인을 생략한다면 현재 문서 도메인에만 쿠키가 접근할 수 있습니다. 

예) coooding.org를 명시하면 dev.coooding.org에도 쿠키가 접근 가능

 

 

(3) 경로 지정

(2) 도메인 명시와 로직이 같습니다. 경로를 지정하면 지정된 경로를 포함하여 하위 경로 페이지만 쿠키가 접근 가능합니다.

 

 

(4) 보안 설정

  • Secure
    •  쿠키는 http, https를 구분하지 않고 전송했다면, Secure적용 시 https 경우에만 전송합니다.
  • HttpOnly
    • XSS 공격 방지 목적으로 자바스크립트에서 접근이 불가하고 HTTP전송에만 사용합니다.
  • SameSite
    • 이름에서 유추해볼 수 있듯 요청한 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키를 전송합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

참고:

https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard