HTTP 헤더

Jaca·2021년 9월 30일
0

HTTP 헤더는 HTTP 전송에 필요한 모든 부가 정보를 담기 위해 존재한다.
표준헤더도 많이 존재하지만, 필요시 임의의 헤더도 만들 수 있다.

HTTP 표준 규격의 등장으로

표현 = 표현 메타데이터 + 표현 데이터

메세지 본문(페이로드) 을 통해 표현 데이터를 전달한다.
표현은 요청이나 응답에서 전달할 실제 데이터
표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공함 (데이터 유형, 데이터 길이, 압축 정보 등)

표현

  • Content-Type : 표현 데이터의 형식 (미디어 타입, 문자 인코딩)
  • Content-Encoding : 표현 데이터의 압축 방식
  • Content-Language : 표현 데이터의 자연 언어 (ko, en)
  • Content-Length : 표현 데이터의 길이

표현 헤더는 전송, 응답 둘다 사용 가능하다.

콘텐츠 협상

클라이언트가 선호하는 표현 요청

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

협상과 우선순위

  • Quality Values(q) 값 사용
    0~1 클수록 높은 우선순위 (생략 시 1)
    Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
    1. ko-kr = 1
    2. ko;q = 0.9
    3. en-US;q = 0,8
    4. en;q = 0.7

  • 구체적인 것을 우선함.
    Accept: text/*, text/plain, text/plain;format=flowed, */*
    1. text/plain;format=flowed
    2. text/plain
    3. text/
    4.
    /*

  • 구체적인 것을 기준으로 미디어 타입을 맞춘다.
    Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,text/html;level=2;q=0.4, */*;q=0.5
    1. text/html;level = 1
    2. text/html = 0.7
    3. text/plain = 0.3
    4. image/jpeg = 0.5
    5. text/html;level=2 = 0.4
    6. text/html;level=3 = 0.7

전송 방식

  • 단순 전송 : Content-Length 를 알 때 일반적으로 보내주는 것

  • 압축 전송 : Content-Encoding 을 알려줘야함

  • 분할 전송 : Transfer-Encoding: chunked, 전체 길이를 예측할 수 없음

  • 범위 전송 : Range로 요청하고, Content-Range 로 응답함

일반 정보

  • From : 유저 에이전트의 이메일 정보
    • 일반적으로 잘 사용되지 않음
    • 검색 엔진에서 주로 사용
    • 요청에서 사용
  • Referer : 이전 웹 페이지 주소
    • A -> B로 이동하는 경우 B를 요청할 때 Referer: A 를 포함해서 요청
    • 유입 경로 분석 가능
    • 요청에서 사용
  • User-Agent : 유저 에이전트 애플리케이션 정보
    • 클라이언트의 애플리케이션 정보(웹 브라우저 정보 등)
    • 통계 정보를 뽑기 좋음
    • 요청에서 사용
  • Server : 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
    • 응답에서 사용
  • Date : 메세지가 발생한 날짜와 시간
    * 응답에서 사용

특별한 정보

  • Host : 요청한 호스트 정보(도메인), 필수
    • 요청에서 사용
    • 하나의 서버가 여러 도메인을 처리해야 할 때
    • 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
  • Location : 페이지 리다이렉션
    • 웹 브라우저는 300대 응답에 Location 헤더가 있으면 Location 으로 자동 이동
    • 201: Location 값은 요청에 의해 생성된 리소스 URI
  • Allow : 허용 가능한 HTTP 메서드
    • 405에서 응답에 포함해야 함
  • Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
    • 503에서 언제까지 불능인지 알려줄 수 있음

인증

  • Authorization : 클라이언트 인증 정보를 서버에 전달
  • WWW-Authenticate : 리소스 접근 시 필요한 인증 방법을 정의
    • 401 응답과 함께 사용

쿠키

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

HTTP는 무상태 프로토콜이기 때문에,
클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.

이를 쿠키를 사용하지 않고 해결하려면 모든 요청과 링크에 사용자 정보를 포함해야하지만 이는,
모든 요청에 사용자 정보가 포함해야한다..

쿠키는 항상 서버에 전송되므로, 네트워크 추가 트래픽을 유발한다.
그러므로 최소한의 정보만 사용하고, 보안에 민감한 데이터는 저장하지 않는다.

ex) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure

쿠키 생명 주기, Expires, max-age

  • 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
  • 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지

쿠키 도메인, domain
명시한 문서 기준 도메인 + 서브 도메인까지 포함한다.

생략시 현재 문서 기준 도메인만 적용된다.

쿠키 경로, path
설정한 이 경로를 포함한 하위 경로 페이지만 쿠키 접근한다.
일반적으로 path=/ 루트페이지 로 지정한다.

쿠키 보안, Secure, HttpOnly, SameSite

  • Secure : 쿠키는 Http, Https를 구분하지 않지만, Secure시 https인 경우에만 전송
  • HttpOnly : XSS 공격 방지, js로 접근 불가, HTTP 전송만 사용
  • SameSite : XSRF 공격 방지, 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

캐시와 조건부 요청

캐시가 없을 때

데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다.
브라우저 로딩 속도가 저하되고, 느린 사용자 경험을 제공하게 된다.

캐시 적용시
캐시 덕분에 캐시가 살아있는 동안에 같은 데이터를 위해 네트워크를 사용하지 않아도 된다.
캐시 유효 시간이 초과하면, 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신한다.

검증 헤더와 조건부 요청

  • 검증 헤더
    • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
    • Last-Modified, ETag
  • 조건부 요청 헤더
    • 검증 헤더로 조건에 따른 분기
    • If-Modified-Since: Last-Modified 사용
    • If-None-Match: ETag 사용
    • 조건이 만족하면 200(다르면), 만족하지 않으면 304(같으면)

캐시가 만약 시간이 초과 되어서 서버에서 다시 요청한다면?

  1. 변경하지 않아서 데이터가 똑같음
  2. 서버에서 기존 데이터를 변경해서 다른 데이터가 됨

1번의 경우 데이터를 새로 받지 않고 저장해 두었던 캐시를 다시 사용한다면 참 좋을것이다..
하지만 이를 위해 캐시와 서버의 데이터가 같다는 것을 확인해야 한다.

이를 위해 If-Modified-Since를 추가 한다.

쿠키가 만료되었을때, 서버의 Last-Modified와 비교하여 같은 데이터인지 확인한다.

같은 데이터일시 304 응답과 함께, 바디 부를 제하고 헤더만 전송하여 클라이언트가 가지고 있는 데이터를 재사용한다.

Last-Modified, If-Modified-Since 의 단점

  • 1초 미만의 단위로 캐시 조정 불가능
  • 날짜 기반의 로직 사용
  • 데이터를 수정해서 날짜가 다르지만, 데이터 결과가 같은 경우 구분 불가
  • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
    • 주석 따위의 큰 영향이 없는 변경에서 캐시를 유지하고 싶은 경우)

ETag

캐시용 데이터에 임이의 고유한 버전 이름을 달아둠
데이터가 변경되면 이 이름을 바꾸어서 변경함(Hash를 다시 생성)
ETag만 비교해서 같으면 유지한다.
로직은 위와 같다.

캐시와 조건부 요청 헤더

  • Cache-Control (캐시 지시어 directives)
    • max-age : 캐시 유효 시간, 초 단위
    • no-cache : 데이터는 캐시해도 되지만, 항상 origin 서버에 검증하고 사용
    • no-store : 데이터에 민감한 정보가 있으므로 저장하면 안됨
      (메모리에서 사용하고 최대한 빨리 삭제)
  • Pragma 캐시 제어 : no-cache의 하위호환
  • Expires 캐시 만료일 지정 : max-age의 하위 호환, max-age와 함께 사용하면 Expires는 무시된다.

프록시 캐시

  • Cache-Control
    • public : 응답이 public 캐시에 저장되어도 됨
    • private : 응답이 해당 사용자만을 위한 것, private 캐시에 저장되어야함 (기본값)
    • s-maxage : 프록시 캐시에만 적용되는 max-age
    • Age: 60 (http 헤더) : origin 서버에서 응답 후 프록시 캐시 내에 머문 시간

캐시 무효화

캐시를 적용하지 않더라도 웹 브라우저들이 GET 요청시 임의로 캐시를 해버린다.
캐시가 되면 안되는 민감한 정보들을 정말 캐시가 되지 않게 설정해주어야 한다.

Cache-Control: no-cache, no-store, must-revalidate, + Pragma: no-cache

  • Cache-Control: must-revalidate
    • 캐시 만료후 최초 조회시 원 서버에 검증해야함
    • origin 서버 접근 실패시 반드시 504 오류가 발생해야함

no-cache가 있는데 must-revalidate가 왜 필요할까?

no-cache는 위 그림과 같은 순간에 프록시 캐시의 데이터를 보여줄 수도 있어서,
좀 더 보수적인 설정을 위해 504 에러를 터뜨리는 must-revalidate가 필요하다!

profile
I am me

0개의 댓글