티스토리 뷰
인프런 김영한 님의 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 듣고 내용을 정리한 글입니다.
1. HTTP 헤더 개요
HTTP 헤더
header-field
는 아래와 같은 형식으로 작성한다.
field-name":" OWS field-value OWS
field-name
다음 콜른(:)은 반드시 붙여 적는다.OWS
는 띄어쓰기 허용이라는 뜻이다.field-name
은 대소문자 구분 없다.field-value
는 대소문자 구분한다.
용도
HTTP 헤더는 HTTP 전송에 필요한 모든 부가정보를 나타낸다.
예를 들면 메세지 바디의 내용, 바디의 크기, 압축, 인증, 요청 클라이언트 정보, 서버 정보, 캐시 관리 정보 등을 표시한다.
표준 헤더 필드가 엄청 많고, 필요 시 임의의 헤더 필드 추가 가능
분류 - RFC2616(과거)
general header
: 메세지 전체에 적용되는 정보. 요청이든 응답이든 구분 없음.- 예) Connection: close
request header
: 요청에 들어가는 정보.- 예) User-Agent: Mozilla/5.0
response header
: 응답에 들어가는 정보.- 예) Server: Apache
entity header
: 엔티티 바디 정보. 메세지 바디에 들어가는 것들에 대한 정보.- 예) Content-Type: text/html, Content-length: 3423
HTTP BODY - 메세지 바디
메세지 본문은 엔티티 본문을 전달하는 데 사용(메세지 바디 안에 엔티티 바디를 넣어서 전달)
엔티티 본문은 요청이나 응답에서 전달할 실제 데이터
엔티티 헤더는 데이터 유형(html, json) 데이터 길이, 압축 정보 등
엔티티 바디의 데이터를 해석할 수 있는 정보를 제공한다.
그러나 이제 엔티티(Entity)가 표현(representation)으로 대체되어 위 엔티티와 관련된 내용은 폐기되었다.
HTTP 표준
- 2014년 RFC7230~7235 등장
- RFC 723x의 변화
- 엔티티(entity)가 표현(representation)으로 대체
- 표현(representation) === 표현 메타데이터(representation metadata) + 표현 데이터(representation data)
왜 표현이라고 할까?
우리는 회원이라는 리소스를 json 혹은 html로 나타낸다. 즉 표현하기 때문이다.
메세지 바디 - RFC7230최신
메세지 바디를 통해 표현 데이터 전달
메세지 바디는 페이로드(payload), 즉 전송되는 데이터이다.
표현은 요청이나 응답에서 전달할 실제 데이터
표현 헤더는 데이터 유형 html, json, 데이터 길이, 압축 정보 등 표현 데이터를 해석할 수 있는 정보 제공한다.
참고: 표현 헤더는 표현 메타데이터와 페이로드 메세지를 구분해야 하지만, 이해상 생략.
2. 표현
표현: 어떤 특정 리소스를 html, json 형태로 표현
Content-Type
: 표현 데이터의 형식(text/html ...)Content-Encoding
: 표현 데이터의 압축 방식Content-Language
: 표현 데이터의 자연 언어(한국어인지 영어인지)Content-Length
: 표현 데이터의 길이(사실 엄밀히 구분하면 payload-length 로 표현 헤더 아님.)
표현 헤더는 전송, 응답 둘다 사용
Content-Type
표현 데이터의 형식 설명
미디어 타입, 문자 인코딩
- text/html; charset=utf-8
- application/json (참고로 기본이 utf-8)
- image/png
Content-Encoding
표현 데이터 인코딩
표현 데이터를 압축하기 위해 사용
데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
- gzip
- deflate
- identity
Content-Language
표현 데이터의 자연 언어
표현 데이터의 자연 언어를 표현
- ko (안녕하세요)
- en (hello)
- en-US
Content-Language
표현 데이터의 길이, 바이트 단위로 나타낸다.
주의할 점은
Transfer-Encoding
전송 인코딩을 사용하면 Content-Length를 사용하면 안된다.
Transfer-Encoding 안에 Content-Length가 이미 들어가 있기 때문이다.
3. 콘텐츠 협상
협상 content negotiation
클라이언트가 선호하는 표현을 서버에게 요청
- accept: 클라이언트가 선호하는 미디어 타입 전달
- accept-charset: 클라이언트가 선호하는 문자 인코딩
- accept-encoding: 클라이언트가 선호하는 압축 인코딩
- accept-language: 클라이언트가 선호하는 자연언어
협상 헤더는 요청 시에만 사용한다.
accept-language 적용 전
한국어 브라우저 사용, GET /event -> 다중 언어 지원 서버, 기본 언어 영어, 한국어는 지원
기본언어가 영어이기 때문에 Content-Language: en, hello 를 먼저 줌
accept-language 적용 후
GET /event, Accept-Language: ko 넣어서 요청 -> 다중 언어 지원 서버의 기본 언어가 영어여도 한국어를 지원한다면 한국어 메세지를 줌
복잡한 예시
Accept-Language: ko -> 다중 언어 지원 서버. 기본은 독일어, 영어는 지원. 한국어는 지원 안 함
위 상항이면 독일어가 온다.
협상과 우선순위1 Quality Values(q)
Quality Values(q) 값 사용
범위는 0~1. 클수록 높은 우선순위.
생략하면 1.
예시
요청을 아래와 같이 한다.
GET /event
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
ko-KR의 우선순위는 1. q 생략하면 1
ko-KR(한국 사람들이 쓰는 한국어), ko(공통 한국어)
클라가 Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
이걸 넣어서 보내면
기본이 독일어고 영어를 지원하지만 한국어를 지원하지 않는 서버는 영어를 보내주게 된다.
협상과 우선순위2
Quality Values(q), 즉 우선순위는 구체적인 것이 우선한다.
Accept: text/_, text/plain, text/plain;format=flowed, _/\*
위 요청문에서는 아래순으로 우선순위
- text/plain;format=flowed
- text/plain
- text/*
- /
협상과 우선순위3
구체적인 것을 기준으로 미디어 타입을 맞춘다.
Accept: text/_;q=0.3,text/html;q=0.7,text/html;level=1,text/html;level=2;q=0.4,_/\*;q=0.5
일 때
text/plain의 우선순위는 0.3이 된다. 명확히 규정되지 않았지만 text/* 안에 들어가기 때문이다.
4. 전송 방식
전송방식 종류
- 단순전송
- 압축전송
- 분할전송
- 범위전송
단순전송
- content-length 사용.
- 한 번 요청하고 콘텐츠 자체를 한 번에 전송 받는 것
압축 전송
- content-encoding 사용
- 전송하기 전에 표현을 압축해서 보냄
분할 전송
- transfer-encoding: chunked 사용
- 용량이 크고, 한 번에 받기까지 시간이 오래 걸릴 때 사용한다.
- 조금씩이라도 먼저 화면에 보여줄 수 있음.
- 여기서는 content-length를 넣으면 안됨
- 처음에 콘텐츠 랭쓰를 예상할 수 없음. 그리고 청크마다 바이트 길이가 따로 다 들어가 있기 때문
분할 전송은 아래와 같이 전송된다.
5
hello
---> 5바이트, hello
5
world
---> 5바이트, world
0
\r\n
---> 끝
범위 전송
Range(요청), Content-range(응답)
- Range: bytes=1001-2000
- Content-Range: bytes=1001-2000 / 2000(끝 길이)
범위 전송을 사용하는 예시로는
이미지를 받는데, 절반 정도 받다가 끊겼다.
처음부터 다시 받으면 용량이 아까우니까 일정 범위를 지정해서 받고자 할 때 범위전송을 사용한다.
5. 일반 정보
Request Header에 들어있는 정보
From
- 유저 에이전트의 이메일 정도를 표시
- 일반적으로 사용되지 않음
- 검색 엔진 같은 곳에서 주로 사용
- 요청에서 사용
Referer
- 이전 웹 페이지 주소
- 현재 요청된 페이지의 이전 웹 페이지 주소
- A -> B로 이동하는 경우, B를 요청할 때 Referer: A를 포함해서 요청
- Referer를 사용해서 유입 경로 분석 가능
- 요청에서 사용
- 참고: referer는 단어 referrer의 오타
User-Agent
- 유저 어플리케이션 정보
- user-agent: Mozilla/5.0 blahblahblahblahblah
- 클라이언트의 애플리케이션 정보(웹 브라우저 정보 등)
- 어떤 특정 브라우저에서만 버그가 생겨 -> 서버 개발자가 로그 등을 분석해서 처리할 수 있음
- 통계 정보에서 많이 사용
- 아 어떤 브라우저에서 많이 들어오는구나
- 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
- 요청에서 사용
Server
- 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
- Server: Apache/2.2.22 (debian)
- server: nginx
- 응답에서 사용.
- ORIGIN 서버: 나에게 응답을 주는 서버. 그 서버까지 가기위해 중간에 존재하는 서버들은 제외.
Date
- 메세지가 발생한 날짜와 시간
- Date: tue,15 Nov 1994 08:12:31 GMT
- 응답에서 사용(과거에는 요청에도 사용했지만, 최신 스펙에서는 응답에서만 사용)
6. 특별한 정보
Host
- 요청한 호스트 정보(도메인)
- 요청에서 사용
- 필수값
- Host: www.google.com
- 하나의 IP에 여러 도메인이 연결되어 있을 때
- 하나의 서버가 여러 도메인을 처리해야 할 때
예시)
가상 호스트를 통해 여러 도메인을 한번에 처리할 수 있는 서버
IP: 200.200.200.2
가 있다고 가정
실제 애플리케이션이 여러 개 구동될 수 있다.(a.com, b.com, c.com)
이때 Host가 없으면
GET /hello HTTP/1.1
위와 같은 요청이 왔을 때, 서버는 어떤 도메인에서 이 요청을 처리해야 할지 알 수가 없음
GET /hello HTTP/1.1
Host: a.com
이렇게 오면 서버가 a.com으로 오는 것으로 알고 처리
Location
- 페이지 리다이렉션
- 웹 브라우저는 3xx응답의 결과에 Location 헤더가 있으면 Location 위치로 자동 이동 - 리다이렉트
- 201 Created Location 값은 요청에 의해 생성된 리소스 URI
- 3xx Redirection Location 값은 요청을 자동으로 리다이렉션하기 위한 대상 리소스
Allow
- 허용 가능한 HTTP 메서드
- 405 Method Not Allowed 에서 응답에 포함해야함
- Allow: GET, HEAD, PUT
- GET,HEAD,PUT 만 지원하는구나~ 하고 클라가 처리
Retry-After
- 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
- 503 service Unavailable: 서비스가 언제까지 불능인지 알려줄 수 있음
- Retry-After: Fri, 31 Dec 1999 23:59:59 GMT(날짜 표기)
- Retry-After: 120(초 단위 표기)
7. 인증
Authorization
- 클라이언트 인증 정보를 서버에 전달
- 예) Authorization: Basic xxxxxxmxmxmxxmxmxmm
- 헤더벨류로 들어가는 값은 인증 방법에 따라 달라진다. oauth 등등
WWW-Authenticate
- 리소스 접근 시 필요한 인증 방법 정의
- 401 Unauthorized 응답과 함께 사용
- 예) WWW-Authenticate: Newauth realm="app",type=1,title="Login to"apps"", Basic realm="simple"
- 응답 메세지 헤더에 들어감
8. 쿠키
Set-Cookie
- 서버에서 클라이언트로 쿠키 전달(응답)
Cookie
- 클라이언트가 서버에서 받은 쿠키를 저장하고 HTTP 요청 시 서버로 전달
쿠키 탄생 배경
처음 welcome 페이지 접근 후 로그인
GET /welcome HTTP/1.1
위와 같은 요청에 대해
HTTP/1.1 200 OK
<html>hello</html>
위와 같이 응답이 온다고 하면,
HTTP는 무상태(stateless) 프로토콜이기 때문에
클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.
클라이언트와 서버는 서로 상태를 유지하지 않는다.
즉, 새로고침 등을 하면 로그인 상태가 해제된다.
대안: 모든 요청에 사용자 정보를 포함한다(쿼리파라미터 등을 이용해서)
근데 모든 요청에 사용자 정보를 포함하면 보안에 매우 취약하고, 개발도 매우 어려워진다.
이런 걸 해결하기 위해 쿠키가 등장
쿠키
쿠키를 사용하는 예시를 보자.
POST를 통해 로그인 시도한다고 하면
서버에서 사용자 정보를
Set-Cookie: user=홍길동
해서 응답한다.
클라이언트는 해당 응답을 받고
쿠키 저장소에 user=홍길동
을 저장해놓음
로그인 이후에 클라이언트에서 쿠키를 읽어서
GET /welcome HTTP/1.1
Cookie: user=홍길동
처럼 헤더에 넣어서 보내준다.
쿠키는 모든 요청에 쿠키 정보를 자동 포함한다.
근데 이렇게 모든 요청에 정보를 담으면 보안에 취약함 -> 세션 이용
예시쿠키) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
사용처
- 사용자 로그인 세션 관리(로그인 정보는 보안 때문에 세션을 이용함 서버가 세션 키를 만들어서 클라에게 내려주면 클라는 요청할 때마다 세션 키를 보내줌)
- 광고 정보 트래킹
쿠키 정보는 항상 서버에 전송됨
- 네트워크 트래픽 추가 유발
- 최소한의 정보만 사용(세션 id, 인증 토큰)
- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(local storage, session storage) 참고
- 서버에 전송할 필요 없이 클라이언트 내부 로직에서만 사용할 데이터는 웹 스토리지에 저장
주의
- 쿠키나 로컬스토리지에는 보안에 민감한 데이터는 저장하면 안됨(주민번호, 신용카드 번호 등)
쿠키 생명주기
Expires, max-age
Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
- 만료일이 되면 쿠키 삭제
Set-Cookie: max-age=3600(3600초)
- 0이나 음수를 지정하면 쿠키 삭제
- 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료 시까지만 유지
- 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지
쿠키 도메인 Domain
domain=example.com
내가 설정한 쿠키가 모든 사이트에 적용되면 큰일남(로그인 등)
명시: 명시한 문서 기준 도메인 + 서브 도메인 포함
- domain=example.com을 지정해서 쿠키 생성
- example.com은 물론이고 dev.example.com도 쿠키 접근
생략: 현재 문서 기준 도메인만 적용
- example.com에서 쿠키 생성하고 domain 지정 생략
- example.com에서만 쿠키 접근
- dev.example.com는 쿠키 미접근
쿠키 경로 path
- 예) path=/home
- 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
- 일반적으로 루트 패쓰 지정 path=/
예) path=/home 지정
- path=/home/123 접근
- path=/home/123/456 접근
- path=/hello 미접근
쿠키 - 보안
Secure, HttpOnly, SameSite
Secure
- 쿠키는 http, https 구분하지 않고 전송
- secure를 적용하면 https인 경우에만 전송
HttpOnly
- xss 공격 방지
- 자바스크립트에서 접근 불가(document.cookie)
- http 전송에만 사용
samesite
- xsrf 공격 방지
- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
- 최신 스펙이라 브라우저 호환성 확인 필요
'Programming > Computer Science' 카테고리의 다른 글
[HTTP] HTTP 캐시와 조건부 요청, 검증 헤더, 프록시 캐시, 캐시 무효화 (0) | 2022.04.17 |
---|---|
[HTTP] HTTP 상태코드, 리다이렉션 (0) | 2022.04.17 |
[HTTP] HTTP 메소드 활용, collection, store, POST 기반 설계, PUT 기반 설계 (0) | 2022.04.01 |
[HTTP] HTTP 메소드, GET, POST, PATCH, PUT, DELETE, 안전, 멱등 (0) | 2022.03.29 |
[HTTP] HTTP 메세지, stateless, 비연결성 (0) | 2022.02.04 |