Today I Learned_221114

5 분 소요

HTTP

인프런 HTTP 강의 수강

HTTP 일반 헤더

헤더 필드의 구성

필드이름 : 필드값
Host: www.google.com
Contemt-Type:text/html;charset=UTF-8

필드 이름은 대소문자 구분이 온다. 스타트 라인 다음에 쭉 헤더들이 오고, 그 다음 메시지 바디 부분이 들어온다.

HTTP 헤더의 용도

  • HTTP 전송에 필요한 모든 부가 정보 (스타트 라인 제외)
  • 필요 시 임의의 헤더 추가가 가능하다.

과거의 헤더 분류(RFC2616)

  • General: 메시지 전체에 적용되는 정보
    • 요청, 응답 상관 없이 메시지 전체에 적용되는 헤더
  • Request: 요청을 보낼 때 정보
    • User-Agent, 웹 브라우저 정보
  • Response: 응답 정보
    • 요청을 받아서 처리하는 서버(아파치 등)
  • Entity: 엔티티 바디 정보
    • Content-Type. 실제 메시지 바디에 들어가는 내용과 관련된 것들

메시지 본문은 엔티티 본문(전달할 실제 데이터)을 전달하는데 사용. 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공

-> 2014년에 RFC7230~7235로 스펙이 쪼개짐 -> 엔티티 바디가 사라짐

엔티티라는 용어가 사라지고 표현(Representation)으로 바뀜

RFC7230 HTTP Body

  • 메시지 본문(페이로드)을 통해 표현 데이터 전달
  • 표현 : 요청이나 응답에서 전달할 실제 데이터 (표현 헤더 + 표현 데이터)
  • 표현 헤더 : 표현 데이터를 해석할 수 있는 정보 제공

표현

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

표현 헤더

  • Content-Type: 표현 데이터가 어떤 형식을 가지고 있는지?
  • Content-Encoding: 표현 데이터의 압축 방식
  • Content-Language: 표현 데이터의 자연 언어(한국어인지?영어인지?)
  • Content-Length: 표현 데이터의 길이

전송과 응답에 모두 사용된다. (명확히는 Payload Header로 쪼개야 함)

Content-Type

Content body에 들어갈 내용이 뭔지?

  • text/html, charset=utf-8
  • application/json
  • image/png

Content-Encoding

데이터를 보내는 곳에서 바디를 압축함 -> 클라이언트가 이걸 풀려면 압축 해제 관련 정보를 가지고 있어야 한다.

데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축을 해제 한다. (gzip, deflate, identity:압축 안 함 등)

Content-Language

ko, en, en-US

다국어 처리 할 수 있다.

Content-Length

Transfer-Encoding을 사용하면 Content-Length를 사용하면 안 된다.

Transfer-Encoding 내부에 Content-Length가 들어가 있기 때문.

콘텐츠 협상(Contents Negotiation)

클라이언트가 원하는 표현 방식대로 달라고 서버에 요청하는 것.

클라이언트의 우선순위에 맞춰서 표현 데이터를 만들어 주는 것.

물론 서버가 못 줄 수도 있지만, 최대한 노력한다.

협상 헤더는 요청시에만 사용한다.

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

Accept-Language 적용 예제

적용되기 전

  • 한국어 브라우저를 사용하여 요청
  • 서버는 기본 영어, 서브 한국어 지원
  • 요청이 오면 기본 값인 영어로 응답을 해 준다.

적용되기 후

  • 위와 같은 경우인데 Accept-Language:ko로 보냄
  • 클라이언트가 원하는 ko로 응답

예외?

  • 한국어 브라우저 사용
  • 서버는 기본 독일어, 서브 영어 지원
  • 클라이언트는 ko로 요청
  • 이거 어떻게 해야 함? -> 우선순위 사용

우선순위, Quality Values(q)

GET /event
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Accept: text/*, text/plain, text/plain;format=flowed, */*
  • 0~1 사이의 값, 클수록 높은 우선순위
  • 생략하면 1 (ko-KR은 생략되었으므로 가장 높은 우선순위인 1이다.)
  • 우선순위에 따라서 값을 보내준다.
  • 구체적인 것이 우선한다.
    • ex : Accept: text/, text/plain, text/plain;format=flowed, */
      1. text/plain;format=flowed
      1. text/plain
      1. text/*
      1. /

전송 방식

단순, 압축, 분할, 범위 전송

단순 전송

요청을 하면 응답을 준다. Content에 대한 길이를 알 수 있을 때 사용한다.

단순하게 한 번에 요청하고 한 번에 쭉 받는다.

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423
<html>
  <body>...</body>
</html>

압축 전송

서버에서 gzip같은걸로 압축해서 보낸다. Content-Encoding을 넣어줘야 한다.

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Encoding: gzip
Content-Length: 521
lkj123kljoiasudlkjaweioluywlnfdo912u34ljko98udjkl

분할 전송

Transfer-Encoding. chunk로 나누어서 보낸다.

용량이 클 때 - 한 번에 쭉 보내면 시간이 오래 걸린다.

분할 전송으로 보내면 오는 대로 바로바로 보내주면 된다.

content-length를 넣으면 안 된다! - 예상이 되지 않음. 내부 chunk에 길이가 다 있다.

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
5
Hello
5
World
0
\r\n

나는 5바이트를 보낼거야 -> Hello -> 나는 5바이트를 보낼거야 -> world -> 끝(0)

범위 전송

이미 절반 받았으니까 나머지 절반 주세요~~

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Range: bytes 1001-2000 / 2000
qweqwe1l2iu3019u2oehj1987askjh3q98y

일반 정보

정보성 헤더들.

From

  • 유저 에이전트의 이메일 정보.
  • 일반적으로 잘 사용되지는 않으나 검색엔진 같은데 주로 사용 (user agent의 이메일 정보). 요청에서 사용

Referer

  • 이전 웹 사이트의 주소. 많이 사용한다.
  • 현재 요청된 페이지의 이전 웹 페이지 주소
  • A -> B로 이동하는 경우 B를 요청할 때 Referer: A를 포함해서 요청한다.
  • 유입 경로 분석이 가능. 어느 사이트를 통해 들어왔는지 분석할 때
  • 요청에서 사용

User-Agent

  • 유저 에이전트 애플리케이션 정보
  • 클라이언트의 애플리케이션 정보(내 웹 브라우저 정보 등)
  • 서버 입장에서 도움이 된다. 특정 브라우저에서 오류가 생기는지 파악하기 위함
  • 요청에서 사용

Server

  • 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
  • HTTP : 중간에 여러 프록시 서버를 거치게 된다. HTTP 응답을 진짜 해주는 서버를 ORIGIN 서버라고 한다.
  • 응답에서 사용

Date

  • 메시지가 발생한 날짜와 시간
  • 응답에 사용(과거에는 요청에서도 사용하긴 했지만 최신 스펙에서는 요청에서 사용한다)

특별한 정보

Host

정말 중요한 헤더! 요청에서 사용하는 필수 헤더이다.

  • 하나의 서버가 여러 도메인을 처리해야 할 때 구분하기 위해 사용한다.
    • 200.200.200.2에 aaa, bbb, ccc 여러 도메인 존재
    • 서버 입장에서는 a, b, c 어디로 들어가야 할지 모른다
    • host 정보로 aaa를 명시해주면 구분해서 들어갈 수 있다.

Location

페이지 리다이렉션

  • 3xx 응답의 결과에 Location 헤더가 있으면 Location 위치로 자동 이동
  • 2xx 응답의 Location값은 요청에 의해 생성된 리소스의 위치를 의미

Allow

허용 가능한 HTTP 메서드

  • 서버가 Allow: GET, HEAD, PUT을 응답으로 보내주면, 클라이언트가 이 3개의 메서드만 지원한다고 파악하면 된다.
    • 이 경우 POST는 지원을 안 한다고 보면 된다.
  • 서버에서 많이 구현되어 있지는 않다.

Retry-After

유저 에이전트가 다음 요청을 할 때까지 기다려야 하는 기간

  • 503 응답 : 서비스가 언제까지 불능인지 알려줄 수 있음
  • 날짜를 표기할 수도 있고, 초 단위로 표기할 수 있다.

인증

Authorization

클라이언트의 인증 정보를 서버에 전달. 인증 방식 마다 들어가는 값이 다르다.

WWW-Authenticate

리소스 접근시 필요한 인증 방법 정의

  • 접근을 했을 때 뭔가 인증이 안되면 401 Unauthorized 응답과 함께 사용한다.
  • 이러한 정보를 가지고 제대로 된 인증을 하라고 응답해준다.

쿠키

Set-Cookie, Cookie 두 개의 헤더 사용

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

쿠키를 사용하지 않으면 클라이언트의 상태를 저장할 수 없다(HTTP는 stateless하므로) -> 그럼 모든 요청에 사용자 정보가 포함되도록 하면 안될까? -> 보안 문제, 모든 요청에 사용자 정보가 포함되도록 개발해야 함, 브라우저 종료 후 재시작 시 곤란하다

서버가 헤더에서 Set-Cookie를 통해 응답을 전달하면 쿠키 저장소에 쿠키를 저장한다.

클라이언트가 서버에게 요청을 할 때 Cookie 헤더가 있으면 쿠키를 찾아서 전달한다.

쿠키 설정 방법

set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
  • expires: 만기일
  • path: 이 경로에 대해 쿠키 설정
  • domain: 해당 도메인에 대한 쿠키 설정
  • Secure: 쿠키에 보안정보 넣기

  • 쿠키의 사용처: 사용자 로그인 세션 관리, 광고 정보 트래킹
    • 보통 유저 정보를 통째로 저장하는게 아니라 세션키를 저장한다
    • 세션id가 있으면 유저 인식
  • 쿠키는 항상 서버에 전송됨
    • 네트워크 트래픽을 추가로 유발하므로, 최소한의 정보(세션id, 인증 토큰)만 사용해야 함
    • 서버에 전송하지 않고 클라이언트가 들고있는 용도로 사용할 경우 - 웹 스토리지(localStorage, sessionStorage) 사용
  • 보안에 민감한 데이터는 저장하지 말자

쿠키의 생명주기

  • expires : 만료일이 되면 쿠키 삭제(GMT 기준으로 입력해야 한다)
  • max-age: 0이나 음수를 지정하면 쿠키 삭제
  • 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지(웹 브라우저 열면 다시 로그인 해야 함)
  • 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지

domain

쿠키에는 도메인 지정 가능

  • 도메인 명시: 명시한 문서 기준 도메인 + 서브도메인 포함
    • domain=a.com 지정하면, dev.a.com도 접근이 가능하다
  • 도메인 생략: 현재 문서 기준 도메인만 적용
    • a.com에서만 접근, dev.a.com 접근 불가

경로(path)

도메인 안에 있는 경로로 필터링. 이 경로를 포함한 하위 경로 페이지만 쿠키 접근

일반적으로 path=/ (루트)로 지정.

쿠키와 관련된 보안

  • Secure
    • 쿠키는 http, https를 구분하지 않고 전송하는데, Secure를 적용하면 https인 경우에만 전송한다.
  • HttpOnly
    • XSS공격 방지, 자바스크립트에서 접근 불가, HTTP 전송에서만 사용
  • SameSite
    • XSRF 공격 방지, 요청하는 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
    • 기능이 적용된 지 얼마 되지 않아 브라우저에서 얼마나 지원하는지 알아보아야 한다.

카테고리:

업데이트: