👩💻 HTTP 헤더
📌 HTTP 헤더 개요
✏️HTTP 헤더의 용도
: HTTP 전송에 필요한 모든 부가정보
- HTTP 전송에 필요한 모든 부가정보 (ex) 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관련 정보 등등 . . .
- 과거의 헤더
- 최신 스펙
📌 표현
✏️표현 관련 헤더
- Content-Type: 표현 데이터 형식
- Content-Encoding: 표현 데이터의 압축 방식
- Content-Language: 표현 데이터의 자연 언어
- Content_Length: 표현 데이터의 길이
- 표현 헤더는 전송, 응답 둘다 사용함
✏️Content_Type
:표현 데이터의 형식 (컨텐츠 바디에 들어가는 바디의 내용이 뭐야?)
- 미디어 타입, 문자 인코딩
- 예)
✏️Content-Encoding
:표현 데이터 인코딩
- 표현 데이터를 압축하기 위해 사용
- 데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
- 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
- 예)
- gzip
- deflate
- identity : 압축을 안한다는 뜻 이다.
✏️Content-Language
:표현 데이터의 자연 언어
- 표현 데이터의 자연 언어를 표현
- 예)
- ko
- en
- en-US
✏️Content-Length
:표현 데이터의 길이
- 바이트 단위
- Transfer_Encoding(전송 코딩)을 사용하면 Content-Length를 사용하면 안됨
📌 협상(콘텐츠 네고시에이션)
✏️클라이언트가 선호하는 표현 요청 (클라이언트가 원하는 표현을 달라고 서버에게 요청을 하는 것,
서버 = "니가 원하는걸로 내가 표현 데이터를 만들어줄게")
- Accept: 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding:클라이언트가 선호하는 압축 인코딩
- Accept_Language:클라이언트가 선호하는 자연 언어
- 협상 헤더는 요청시에만 사용
✏️Accept-Language 적용 전,후와 복잡한 예시
한국어 브라우저를 사용하여 어떤 외국에 있는 이벤트 사이트를 들어간다.
그러면 다중 언어를 지원하는 서버는 기본값인 영어로 한국어 브라우저에 응답을 해준다.
하지만 클라이언트가 서버 요청을 할때 Accept-Language:ko 하여 만약에 "내가 선호하는 언어는 ko에요"라고 말하면 서버는 기본이 영어지만 한국어도 지원하기 때문에 content-Language를 ko로 바꾸어 한국어로 응답해준다.
다중언어를 지원하는 서번데 기본이 독일어이고 영어도 지원한다. 나는 한국어로 요청했는데 다중 언어 지원 서버가 한국어를 지원하지 않으니 기본값인 독일어로 응답을 해준다.
✏️협상과 우선순위1
:Quality Values(q)
- Quality Values(q) 값을 사용
- 0 ~ 1, 클수록 높은 우선순위
- 생략하면 1
- Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.8
- 1. ko-KR;q=1 (q생략) 한국어
- 2. ko;q=0.9 한국 공통어
- 3. en_US;q=0.8 US에서 쓰는 영어
- 4. en;q=0.7 영어
✏️협상과 우선순위2
:Quality Values(q)
- 구체적인 것이 우선한다.
- Accept: text/*, text/plain, text/plain;format=flowed, */*
- 1. text/plain;formate=flowed
- text/plain
- text/*
- */*
✏️협상과 우선순위2
:Quality Values(q)
- 구체적인 것을 기준으로 미디어 타입을 맞춘다.
📌 전송 방식 설명
✏️전송 방식 설명
- 단순 전송
- 압축 전송
- 분할 전송
- 범위 전송
✏️ 단순 전송 (Content-Length)
:그냥 요청을 하면 준다.
- Content에 대한 길이를 알고 있을 때 사용해야 한다.
- 그럼 길이 값을 준다.
✏️ 압축 전송 (Content-Encoding)
:서버에서 gzip같은 것으로 압축하여 용량을 줄이는 것
- Content-Encoding을 추가로 넣어주어야 한다.
✏️ 분할 전송 (Transfer-Encoding)
:쪼개서 전송한다. 용량이 엄청 클 때 한번에 보내면 기다려야하기 때문에 분할로 전송하면 오는대로 바로바로 표시할 수 있다.
:Content-Length를 넣으면 안됨
✏️ 범위 전송 (Range, Content-Range)
:이미지를 절반 정도 받다가 끊겼을때, 다시요청하면 용량이 아까우니 범위를 지정해서 요청할 수 있다.
"나는 이미 절반 받았으니 절반만 주세요"
📌 일반 정보
✏️일반 정보
- From: 유저 에이전트의 이메일 정보 (잘 사용 안함)
- 일반적으로 잘 사용되지 않음
- 검색 엔진 은 곳에서 주로 사용
- 요청에서 사용
- Referer: 현재 요청된 페이지의 이전 웹 페이지 주소 (자주 사용 함)
- A사이트 -> B사이트로 이동하는 경우 B를 요청할 때 Referer:A 를 포함해서 요청
- ex) www.google.com 에서 나무위키를 검색해서 들어간다면 referer은 www.google.com으로 남게 된다.
- Referer를 사용해서 유입 경로 분석 가능
- 요청에서 사용
- A사이트 -> B사이트로 이동하는 경우 B를 요청할 때 Referer:A 를 포함해서 요청
- User-Agent: 유저 에이전트 애플리케이션 정보 ( 클라이언트 애플리케이션 정보 )
- user-agent: Mozilla/5.0 (Macintosh; Intel Maac Ox X 10_15_7) AppleWebKit/537...
- 클라이언트의 애플리케이션 정보(웹 브라우저 정보, 등등)
- 통계 정보
- 어떤 종류의 브라우저에서 장애가 발생하는 파악 가능
- 요청에서 사용
- Server: 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
- ORIGIN서버란? : HTTP 요청을 보내면 중간의 여러 프록시 서버를 거치게 된다. 실제로 나의 요청을 받아서 HTTP 응답을 해주는 서버를 (진짜 나의 요청이 있는 마지막 서버) ORIGIN 서버 라고 한다.
- Server: Apache/2.2.22 (Debian)
- server: nginx
- 응답에서 사용
📌 특별한 정보
✏️ 특별한 HTTP 정보
- Host: 요청한 호스트 정보(도메인) (매우 중요함. 필수값임)
- 하나의 서버가 여러 도메인을 처리해야 할 때
- 하나의 IP 주소에 여러 도메인이 적용되어 있을 때가 있다. 그때 구분을 해준다.
서버는 하나의 도메인만 처리하는 것이 아닌 여러 도메인을 처리할 수도 있다. 이때 클라이언트가 서버에 요청을 보냈을 때 서버가 여러 도메인을 가지고 있다면 클라이언트와 서버는 IP로만 통신하기에 서버는 클라이언트가 보낸 /hello가 aaa.com에 관련된 애플리케이션에 들어가야할지, bbb.com에 관련된 애플리케이션에 들어가야할지 구분 할 방법이 없다. 그래서 필수로 HTTP헤더에 host로 도메인을 넣어 서버가 구분을 할 수 있도록 만들어 준다.
- Location: 페이지 리다이렉션
- 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
- 응답코드 3xx에서 설명
- 201 (Created): Location 값은 요청에 의해 생성된 리소스 URI
- 3xx (Redirection): Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를 가리킴
- Allow: 허용 가능한 HTTP 메서드
- 405 (Method Not Allowed)에서 응답에 포함해야함
- Allow: GET, HEAD, PUT
- ex) GETM, HEAD, PUT만 지원합니다. 라고 알려줌. POST가 있지 않으니 "클라이언트가 아 POST를 하면 안되는구나" 알게됨
- Retry-After:유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간 (잘 사용 안함)
- 503 (Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
- Retry-After: Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
- ex) 서버 점검이 6시부터 7시면 Retry-After에 날짜와 7시를 표기하면 된다.
- Retry-After: 120 (초 단위 표기)
- ex) 몇 분만 기다려야 한다면 초 단위로 표기도 가능하다.
📌 인증
✏️ 인증과 관련된 헤더
- Authorization: 클라이언트 인증 정보를 서버에 전달
- Authorization: Basic xxxxxxxxxxxxxxxx
- WWW-Authenticate:리소스 접근시 필요한 인증 방법 정의
- 리소스 접근시 필요한 인증 방법 정의
- 401 Unauthorized 응답과 함께 사용
- WWW-Authenticate: Newauth realm="apps", type = 1, title="Login to \"apps\"",Basic realm="simple"
📌 쿠키
✏️ Cookie란 무엇일까?
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
"쿠키를 미사용 하였을 때"
"쿠키를 미사용 하였을 때"
처음 welcome 페이지로 접근하면 "안녕하세요 손님"라는 응답이 온다. 이후 홍길동이라는 유저가 로그인을 하면 "홍길동님이 로그인했습니다."라는 응답이 오고, 로그인 이후 welcome 페이지로 접근을 하면 유저는 "안녕하세요. 홍길동님"이라는 응답을 기대하였지만 돌아오는 응답은 "안녕하세요. 손님"이라는 응답이다.
왜냐하면 /welcome이라고 보냈는데 이는 서버입장에서는 홍길동이 보낸 요청인지 아닌지를 구분할 수 있는 방법이 없다.
HTTP는 무상태 프로토콜이다. 요청과 응답을 주고 받으면 바로 연결을 끊어버리기에 유저가 홍길동인지를 알 수 없다.
(무상태가 기억이 나지 않으면 다시 블로그 포스팅을 통해 공부하고 오자.)
이를 위한 대안 방법은 모든 요청에 사용자 정보를 포함하는 것이다. 하지만 개발자가 모든 요청과 링크에 사용자 정보를 포함하기에는 너무 복잡해지고 보안면에서도 문제가 생기게 된다. (아래의 사진 참고)
"쿠키를 사용하였을 때"
"쿠키를 사용 하였을 때"
웹 브라우저가 POST로 로그인 하여 user는 홍길동 이라고 보낸다. 그러면 서버는 Cookie에 유저는 "홍길동"을 말게되고, 이 데이터를 SetCookie라고 하는 쿠키 헤더를 하나 만들어서 응답한다.
웹 브라우저 내부에는 쿠키 저장소가 있다. 웹 브라우저는 User는 홍길동이라는 데이터 값을 저장한다. 서버가 응답해서 만든 SetCookie라고 보낸 key는 user이고 value는 홍길동 이다.
로그인 이후에 웹 브라우저가 welcome 브라우저에 들어가게 되면 자동으로 웹 브라우저는 이 서버에 요청을 할 때마다 쿠키 저장소를 무조건 뒤지고, 있으면 꺼내서 Cookie: user = 홍길동 이라는 http 헤더를 만들어서 서버에 보낸다. 그러면 서버는 쿠키를 열어서 유저가 홍길동 이라는 것을 알 수 있게 되어 "안녕하세요. 홍길동님"이라고 할 수 있는 것이다.
✏️ Cookie
- 예) set_cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
- sessionId: 유저의 정보를 그대로 저장하면 보안상의 문제가 있기 때문에 서버는 로그인이 성공 되면 sessionIdKey라는 것을 서버에서 만들어서 유저의 정보를 저장하게 된다. 그러면 클라이언트가 서버에 요청할 때마다 sessionId로 계속 보내는 것이다. 서버는 sessionId가 있으면 "아 얘가 홍길동이구나"라고 서버에서 알 수 있다.
- 사용처
- 사용자 로그인 세션 관리
- 광고 정보 트래킹
- 쿠키 정보는 항상 서버에 전송됨
- 네트워크 트래픽 추가 유발
- 최소한의 정보만 사용(세션 id, 인증 토근)
- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지 (localStorage, sessionStorage)참고 (요청할 때마다 사용하는 것이 아니라 클라이언트가 보관하고 필요할때만 클라이언트 로직에서 꺼낼수있도록 하는 것)
- 주의!
- 보안에 민감한 데이터는 저장하면 안됨(주민번호, 신용카드 번호 등등)
✏️ 쿠키의 생명주기: Expires, max=age;
- Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
- 만료일이 되면 쿠키 삭제
- Set-Cookie: max-age=3600 (3600초)
- 0이나 음수를 지정하면 쿠키 삭제
- 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지 (웹 브라우저를 완전히 껐다가 키면 다시 로그인 해야되는 등의 예)
- 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지
✏️ 쿠키 - 도메인
:내가 지정한 쿠키가 아무 사이트에 들어갈 때마다 생성되면 큰일난다
- domain = example.org
- 명시: 명시한 문서 기준 도메인 + 서브 도메인 포함
- domain=example.org를 지정해서 쿠키 생성
- example.org는 물론이고, dev.example.org도 쿠키 접근
- domain=example.org를 지정해서 쿠키 생성
- 생략: 현재 문서 기준 도메인만 적용
- example.org에서 쿠키를 생성하고 domain 지정을 생략함
- example.org는 쿠키 접근
- dev.example.org는 쿠키 미접근
- example.org에서 쿠키를 생성하고 domain 지정을 생략함
✏️ 쿠키 - 경로
:도메인으로 한번 필터를 하고 경로를 추가로 하여 필터를 함
- 예) path=/home
- 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
- 일반적으로 path=/ 루트로 지정 (왜냐하면 한 도메인 안에서 보통 쿠키를 다 전송하기를 원함)
- ex)
- path=/home 지정
- /home -> 가능
- /home/level1 -> 가능
- /home/level1/level2 -> 가능
- /hello -> 불가능
✏️ 쿠키 - 보안
:Secure, HttpOnly, SameSite
- Secure
- 쿠키는 http, https를 구분하지 않고 전송
- Secure를 적용하면 https인 경우에만 전송
- GttpOnly
- XSS 공격 방지
- 자바스크립트에서 접근 불가
- HTTP 전송에만 사용
- SameSite
- XSRF 공격 방지
- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키 전송
'CS > HTTP' 카테고리의 다른 글
[HTTP] 모든 개발자를 위한 HTTP 웹 기본 지식 - 8 (0) | 2024.01.04 |
---|---|
[HTTP] 모든 개발자를 위한 HTTP 웹 기본 지식 - 6 (0) | 2024.01.03 |
[HTTP]모든 개발자를 위한 HTTP 웹 기본 지식 - 5 (0) | 2024.01.03 |
[HTTP]모든 개발자를 위한 HTTP 웹 기본 지식 - 4 (0) | 2023.12.28 |
[HTTP]모든 개발자를 위한 HTTP 웹 기본 지식 - 3 (0) | 2023.12.26 |