섹션 7: HTTP 헤더 1 - 일반 헤더

MineeHyun·2024년 7월 31일
0

HTTP 헤더 개요

RFC2616 표준 (이었던 것)

  • HTTP 헤더
    • 용도: HTTP 전송에 필요한 모든 부가 정보
    • header-field: field-name":" OWS field-value OWS
      • OWS: 띄어쓰기 허용
      • field-name은 대소문자 구분 없음
  • 메세지 본문은 엔티티 본문을 전달하는 데 사용
    • 엔티티 본문 (entity body)는 요청이나 응답에서 전달할 실제 데이터
    • 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공
      • 데이터 유형 (html, json), 데이터 길이, 압축 정보 등

2014년 RFC7230~7235 등장

  • RFC2616 폐지
  • Entity -> Representation (표현)
    • 표현 = 표현 메타데이터 + 표현 데이터
  • 메세지 본문을 통해 표현 데이터 전달
    • 메세지 본문을 페이로드 (payload)라고도 한다.
    • 표현은 요청이나 응답에서 전달할 실제 데이터
    • 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공 (데이터 유형, 데이터 길이, 압축 정보 등등)
    • (참고) 표현 헤더는 표현 메타데이터와 페이로드 메세지를 구분해야 하지만 ... 너무 복잡해지니까 생략

표현

  • 표현이란: 리소스 (추상적인 것)을 서버와 클라이언트가 서로 주고받기 위해 구체화하는 것
    • html 형식의 표현을 전달할 거야... 리소스를 json 형식으로 표현해서 전달할 거야...

표현 헤더의 요소

: 표현 헤더는 전송, 응답에 둘다 사용할 수 있다.

  • Content-Type: 표현 데이터의 형식
    • body에 들어가는 내용이 뭐야: html, json, ...
    • 미디어 타입, 문자 인코딩 형식
    • (예) text/html; charset=utf-8, application/json, image/png ...
  • Content-Encoding: 표현 데이터의 압축 방식
    • 표현 데이터를 압축하기 위해 사용
    • 데이터를 전달하는 곳에서 압축한 뒤 인코딩 헤더 추가
    • 데이터를 읽는 쪽에서 이 정보를 보고 압축을 해제해서 사용한다
    • 데이터를 사용하려면 어떻게 압축되어 있는지 알아야 하기 때문에 필요
    • (예) gzip(압축), deflate, identity(압축 전후가 똑같다: 압축 안 했다)...
  • Content-Language: 표현 데이터의 자연 언어 (한국어인지 영어인지...)
    • 표현 데이터의 자연 언어를 표현
    • (예) ko, en, en-US
    • 클라이언트가 요청 메세지의 Content-Language를 보고 언어마다 다른 페이지를 보여주거나... 하는 식으로 구현할 수도 있다.
  • Content-Length: 표현 데이터의 길이
    • 바이트 단위의 길이
    • Transfer-Encoding (전송 코딩)이라는 게 있는데 요걸 사용하면 Content-Length를 사용하면 안됨.
      • Transfer-Encoding 안에 이미 이 정보가 다 들어있기 때문에

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

  • 클라이언트가 선호하는 표현 요청
  • 협상 헤더는 요청 시에만 사용 (클라이언트 -> 서버)
  • 원하는 대로 해달라고 요청했지만 서버가 못해줄 수도 있음 (!) 어쩔 수 없다.
  • Accept: 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
  • Accept-Language: 클라이언트가 선호하는 자연 언어
    • 원하는 언어로 달라고 요청
    • 서버가 다중 언어로 되어 있고, 기본값이 영어일 때
      • 요청 메세지에 국가 정보가 없으면 영어 페이지를 반환
      • 요청 메세지에 Accept-Language: ko로 보내면 한국어 페이지를 반환 (만약 서버가 한국어를 가지고 있으면)
    • 서버가 다중 언어로 되어 있고, 기본값이 독일어이고, 한국어가 없을 때
      • Accept-Language를 ko로 보내도, 서버에 한국어 페이지가 없으니까 기본값인 독일어가 나옴 (쉽지않음)
      • => 우선순위를 도입
      • 한국어 -> 영어 순으로 되어 있는 우선순위로 보내면, 한국어가 없으니 다음 우선되는 언어로 영어를 선택해 보내준다

협상과 우선순위 (1)

  • Quality Values (q) 값 사용
  • 0~1, 1에 가까울수록 높은 우선순위를 가짐 (생략하면 1)

협상과 우선순위 (2)

  • 구체적인 것이 우선한다.
  • (예) Accept: text/, text/plain, text/plain;format=flowed, /*
    • text/plain;format=flowed, text/plain, text/, /* 순으로 높은 우선순위를 갖는다.

협상과 우선순위 (3)

  • 구체적인 것을 기준으로 미디어 타입을 맞춘다.

전송 방식

  • 단순 전송
    • Content-Length 사용: 컨텐츠의 길이를 알 수 있을 때 쓴다.
    • 한 번에 요청하고 한 번에 단순하게 쭉 받는 것
  • 압축 전송
    • Content-Length, Content-Encoding 사용: 압축해서 보내는 것.
  • 분할 전송
    • Transfer-Encoding 사용: 분할 전송
      • 바디에 청크의 길이/데이터 형식으로 분할해서 기록
      • Content-Length를 넣으면 안된다.
        (1) length를 예상할 수 없다.
        (2) 청크마다 이미 length를 가지고 있다.
  • 범위 전송
    • Range, Content-Range 사용
      • 일부는 이미 받아서 가지고 있고, 나머지만 전송받고 싶을 때 사용

일반 정보

  • 정보성 헤더
  • From: 유저 에이전트의 이메일 정보
    • 일반적으로 잘 사용되지 않음
  • Referer: 이전 웹 페이지의 주소
    • 현재 요청된 페이지의 이전 페이지의 주소
    • A -> B로 이동하는 경우 B를 요청할 때 Referer A를 포함해서 요청
    • 유입 경로 분석할 때 사용할 수 있다. 요청 메세지에 사용함.
    • (참고) referer는 referrer의 오타...
  • User-Agent
    • 유저 에이전트 클라이언트 애플리케이션 정보
    • 웹 브라우저 정보 등...
    • 특정 브라우저에서 버그가 생기거나 사용자 경향을 확인하는 등 통계를 볼 때 사용할 수 있다.
    • 요청 메세지에 사용함.
  • Server: 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
    • 오리진 서버: 중간에 거치는 프록시 서버들 말고 요청에 응답하는 진짜 서버를 오리진 서버라고 한다 (표현 데이터를 만들어 주는 서버)
    • 응답 메세지에 사용
  • Date: 메세지가 발생한 날짜와 시간
    • 응답에서만 사용
    • 과거에는 요청에서도 사용했지만 최신에는 응답에서만 사용

특별한 정보

  • Host: 요청한 호스트 정보 (도메인)
    • 요청에서 사용, 필수
    • 하나의 서버가 여러 도메인을 처리해야 할 때
    • 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
    • 호스트 헤더가 없는 요청을 보내면, 이런 상황들에서 어떤 도메인으로 처리해야 할지 알 수 없다. 그래서 호스트는 꼭 있어야 함!
  • Location: 페이지 리다이렉션
    • 웹 브라우저는 3xx 응답의 결과에 이 헤더가 있으면 Location 위치로 자동 이동한다.
  • Allow: 허용 가능한 HTTP 메서드
    • URL 경로는 있는데 GET, HEAD, PUT만 허용하고 POST는 지원하지 않을 때
      • POST 요청이 오면, 405 (Method Not Allowed) 응답에 Allow 헤더를 포함시켜 돌려보내야 한다.
      • Allow: GET, HEAD, PUT이라고 보내면 됨
  • Retry-After 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
    • 503 (Service Unavailable) 서비스가 언제까지 불능인지 알려줄 수 있음
      • 서버 점검을 하거나... 그럴 때
      • 종료 시점의 날짜 표기, 남은 시간을 표기 등

인증

  • Authorization: 클라이언트 인증 정보를 서버에 전달
    • 인증하는 여러가지 메커니즘이 있는데 그것마다 값이 다르다.
  • WWW-Authentication
    • 리소스 접근 시 필요한 인증 방법 정의
    • 401 Unauthorized 응답에 넣어서 인증 방법을 클라이언트에게 알려 줘야 한다.

쿠키

  • Stateless: 서버와 클라이언트가 서로의 상태를 유지하지 않음!
    • 로그인을 하거나... 여러 상황에서, 문제가 생길 수 있음
    • URL과 모든 요청에 서버가 필요로 하는 모든 정보를 적어서 보내면 된다
      • 하지만 쉽지 않겠죠 (개발도 어렵고 보안 상의 문제도 있음)
      • 브라우저를 완전히 종료하고 다시 열면 이 고생도 헛수고가 된다. (웹 스토리지라는 걸 써서 해결할 순 있지만 번거롭고 힘들다!)

쿠키의 등장

  • 서버는 요청을 받으면, 쿠키를 만들어서 Set-Cookie 헤더에 적어 보냄.
  • 클라이언트 (웹 브라우저)는 쿠키 저장소를 가지고 있음. 이렇게 받은 쿠키를 쿠키 저장소에 넣어둠.
  • 클라이언트가 다시 요청을 보낼 때, 쿠키 저장소를 무조건 뒤져서 쿠키를 꺼내서 Cookie 헤더에 적어 보냄. (모든 요청 정보에 쿠키를 자동으로 포함)
  • 서버는 이걸 보고 클라이언트의 이전 상태를 파악할 수 있음!
  • 좋은 점: 쿼리문을 쓰거나 URL이 지저분해지거나 하지 않는다. 개발자도 편하고 좋다.
  • 쿠키의 주 사용처: 사용자 로그인 세션 관리, 광고 정보 트래킹
  • 쿠키 정보는 항상 서버에 전송됨
    • 네트워크 트래픽 추가 유발 -> 최소한의 정보만 사용 (세션 id, 인증 토큰처럼 꼭 있어야 하는 것만 사용)
    • 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지를 사용하면 됨
      • 쿠키는 일단 세팅하면 무조건 서버에 보내버리기 때문에... 클라이언트가 들고 있다가 필요할 때만 로직으로 꺼내 쓰고 싶을 때는 웹 스토리지 같은 것을 쓰면 된다.
  • 주의!!!! 쿠키든 웹 스토리지든 보안에 민감한 데이터는 절대 저장하면 안됨.
  • Set-Cookie: 서버에서 클라이언트로 쿠키 전달 (응답)
    • 쿠키를 만들어서 보낼 때 제약 조건을 정해 놓는다.
    • sessionId, expire (쿠키의 만료시점), path (쿠키가 허용되는 경로), Secure (쿠키의 보안 정보)
  • Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고 HTTP 요청 시 서버로 전달

쿠키의 생명주기

  • 쿠키가 영생을 살 순 없으니 끝나는 시점을 정해 준다. Set-Cookie에 넣어서 만들면 된다.
    • expires=날짜 (GMT 기준)
      • 만료일이 되면 쿠키가 자동으로 삭제됨
    • max-age=숫자 (초 단위)
      • 0이나 음수를 지정하면 쿠키가 삭제됨
    • 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료할 때까지만 유지
    • 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지

쿠키: 도메인

  • Set-Cookie에 domain을 지정해서 보낼 수 있다. (domain=example.org)
  • domain을 지정해 두면 지정된 도메인에서만 쿠키를 전송한다.
    (1) 명시하는 경우: 명시한 문서를 기준으로 서브 도메인에도 쿠키를 보낸다.
    (2) 생략하는 경우: 생성한 문서를 기준으로만 쿠키를 보낼 수 있음
    • example.org에서 쿠키를 생성하고 domain을 생략하면 example.org에만 쿠키를 보냄.

쿠키: 경로

  • path=/home
    • 이 경로를 포함한 하위 경로 페이지만 쿠키에 접근할 수 있음
    • 도메인으로 한 번 필터를 하고 도메인 안에서 경로를 한 번 더 필터링 하는 것
    • 일반적으로 path=/루트로 지정

쿠키: 보안

  • Secure
    • 쿠키는 원래 http, https를 구분하지 않고 전송
    • secure를 적용하면 https인 경우에만 전송
  • HttpOnly
    • XSS 공격 방지
    • 자바스크립트에서 접근 불가
    • HTTP 전송에만 사용
  • SameSite
    • XSRF 공격 방지
    • 현재 내가 요청하는 도메인과 쿠키에 설정된 도메인이 완전히 같은 경우에만 쿠키를 전송함
    • 기능이 적용된지 별로 되지 않아서 브라우저의 적용 범위를 확인한 뒤 사용할 것

0개의 댓글