Header, Cookie
헤더/쿠키 매개변수는 Header, Cookie 클래스를 반드시 사용해야 한다.
- 헤더
- 프로토콜의 헤더의 내용은 특정 프로토콜의 기능을 제공하기 위해 담고 있는 최소한의 정보
- 클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 해줌
- 대소문자를 구분하지 않음
- 이름:값 형태
- HTTP 쿠키(웹 쿠키, 브라우저 쿠키)
- 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각
- 사용자의 브라우저는 그 데이터 조각(쿠키)들을 저장해 놓았다가 동일한 서버에 재 요청 시 저장된 데이터를 함께 전송
- 두 요청이 동일한 브라우저에서 들어왔는지 아닌지를 판단할 때 주로 사용
- 무상태 프로토콜 (stateless protocol) 속성을 보완
쿠키
쿠키는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각이라고 했다. 이제 쿠키를 왜 사용하는지 알아보자.
인터넷을 통신해주는 HTTP는 계속 연결되어 있지 않다. 만약에 google.com에서 ‘안녕’을 검색하면 클라이언트는 google.com 서버에 ‘안녕’을 요청하고, google.com 서버에서 ‘안녕’에 대한 정보만 응답으로 주고 연결이 끊어진다. 이것을 무상태 프로토콜(stateless protocol) 이라고 한다.
다시말해서 모든 HTTP 요청들은 완전히 독립된다는 의미이다. 즉, 전후 요청에 영향을 받지 않고, 서버는 매번 요청을 처리할 때마다 독립적으러 처리하게 되어 HTTP 프로토콜은 많은 정보량을 가지게 된다. 따라서 웹 서버는 이러한 무상태 속성을 극복하기 위해 쿠키를 사용했다.
쿠키를 사용하지 않았을 때
쿠키를 사용하지 않았을 때는 클라이언트가 새로운 요청을 보내면 웹 서버에서는 이전 요청을 기억하지 못하면서 현재 상태가 유지되지 않는다. 예를 들어 구글 홈페이지에 로그인을 했는데, 검색을 했더니 로그인이 되어있지 않는 상태이다. 이렇게 되면 페이지를 이동할 때마다 계속 로그인을 해줘야 하는 문제가 발생한다.
쿠키를 사용했을 때
쿠키를 사용했을 때 우리가 구글에 로그인을 했다고 하면 구글 웹 서버에서는 set-Cookie에 정보를 담아서 응답을 준다. 그러면 웹 브라우저의 별도의 쿠키 저장소에 정보를 저장하게 되고, 클라이언트가 다시 웹 서버에 요청을 보낼때 웹 브라우저의 쿠키 저장소를 한번 조회한다. 쿠키 안에 로그인 정보를 같이 보내서 구글 웹 서버에 로그인이 되었다는 것을 확인시켜준다.
쿠키의 용도
쿠키는 다음과 같이 사용된다. 쿠키 정보는 서버에 전송되며 최소한의 정보만 사용하고, 웹 브라우저에 저장되기 때문에 보안에 민감한 데이터는 저장하면 안된다. (주민번호 등)
- 세션 관리(Session management)
- 서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보 관리
- 개인화(Personalization)
- 사용자 선호, 테마 등의 세팅
- 트래킹(Tracking)
- 사용자 행동을 기록하고 분석하는 용도
쿠키 만들기 (Set-Cookie, Cookie header)
HTTP 요청을 수신할 때, 서버는 응답과 함께 Set-Cookie 헤더를 전송할 수 있다. 쿠키는 보통 브라우저에 저장되며, 그 후 쿠키는 같은 서버에 의해 만들어진 요청들의 Cookie HTTP 헤더안에 포함되어 전송된다.
Set-Cookie HTTP 응답 헤더는 서버에서 사용자에게 전송된다. 간단한 쿠키는 다음과 같이 설정될 수 있다.
Set-Cookie: <cookie-name>=<cookie-value>
이 서버 헤더는 클라이언트에게 쿠키를 저장하라고 전달한다. 그러면 아래와 같은 형태로 전달된다.
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]
이제 서버로 새로운 요청을 보낼 때, 웹 브라우저는 쿠키 헤더를 사용해 이전에 저장했던 모든 쿠키들을 서버로 전송한다.
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
쿠키 가져오기
ga라는 변수에 쿠키를 명시해주고 받은 값(쿠키)를 리턴해주는 간단한 함수이다.
from fastapi import FastAPI, Cookie
app = FastAPI()
@app.get("/cookie")
def get_cookies(ga: str = Cookie(None)):
return {"ga": ga}
HTTPie에서 쿠키는 Cookie:
(fastapi) PS D:\workspace> http -v :8000/cookie Cookie:ga=abc
GET /cookie HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: ga=abc
Host: localhost:8000
User-Agent: HTTPie/3.2.1
HTTP/1.1 200 OK
content-length: 12
content-type: application/json
date: Sun, 14 Aug 2022 04:11:04 GMT
server: uvicorn
{
"ga": "abc"
}
쿠키를 사용하는 게 데이터를 클라이언트 측에 저장할 수 있는 유일한 방법이었을 때는 이 방법이 타당했지만, 지금은modern storage APIs를 사용해 정보를 저장하는 걸 권장한다. 모든 요청마다 쿠키가 함께 전송되기 때문에 (특히 mobile data connections에서) 성능이 떨어지는 원인이 될 수 있다.
헤더
헤더는 특정 프로토콜의 기능을 제공하기 위해 담고 있는 최소한의 정보이다. 헤더의 종류는 몇 가지 예시는 다음과 같다.
- General header
- 요청과 응답 모두에 적용되지만 바디에서 최종적으로 전송되는 데이터와는 관련이 없는 헤더
- Date
- HTTP 메시지를 생성한 일시 (RFC 1123에서 규정)
Date: Sat, 2 Oct 2018 02:00:12 GMT
- Connection
- 클라이언트와 서버 간 연결에 대한 옵션 설정(다소 모호한 복잡성 있음)
Connection: close
- 현재 HTTP 메시지 직후에 TCP 접속을 끊는다는 것Connection: Keep-Alive
- 현재 TCP 커넥션을 유지
- Request header
- 패치될 리소스나 클라이언트 자체에 대한 자세한 정보를 포함하는 헤더 (요청 메세지에만 나타남)
- Host
- 요청하는 호스트에 대한 호스트명 및 포트번호 (필수)
- Cookie
- 서버에 의해 Set-Cookie로 클라이언트에게 설정된 쿠키 정보
- From
- 클라이언트 사용자 메일 주소
- Referer
- 바로 직전에 머물렀던 웹 링크 주소
- Accept
- 클라이언트 자신이 원하는 미디어 타입 및 우선순위를 알림
- 텍스트(text/html,text/plain,…),이미지(image/jpeg,…) 등
Accept: */*
: 어떤 미디어 타입도 가능Accept: image/*
: 모든 이미지 유형이 가능
- Response header
- 위치 또는 서버 자체에 대한 정보(이름, 버전 등)와 같이 응답에 대한 부가적인 정보를 갖는 헤더
- Server
- 서버 소프트웨어 정보
- Accept-Range
- Set-Cookie
- 서버측에서 클라이언트에게 세션 쿠키 정보를 설정 (RFC 2965에서 규정)
- Expires
- 리소스가 지정된 일시까지 캐시로써 유효함을 나타냄. 즉, 응답 컨텐츠가 언제 만료되는지
Expires: Thu, 26 Jul 2018 07:28:00 GMT
- Entity header
- 컨텐츠 길이나 MIME 타입과 같이 엔티티 바디에 대한 자세한 정보를 포함하는 헤더
- Content-Type
- 해당 개체에 포함되는 미디어 타입 정보
- 컨텐츠의 타입(MIME 미디어 타입) 및 문자 인코딩 방식(EUC-KR,UTF-8 등)을 지정
Content-Type: text/html; charset-latin-1
: 해당 개체가 html 텍스트 문서이고, iso-latin-1 문자 인코딩 방식으로 표현되는 것을 의미
- Content-Language
- 해당 개체와 가장 잘 어울리는 사용자 언어
- Content-Encoding
- 해당 개체 데이터의 압축 방식
Content-Encoding: gzip, deflate
: Content-Encoding 및 Content-Length 2개 항목을 토대로 압축 해제가 가능
헤더 가져오기
헤더에 X- 접두어는 사용자 정의 헤더라는 것을 의미한다. 표준 헤더와 구분짓기 위해 많이들 사용한다.
(fastapi) PS D:\workspace> http -v :8000/header X-Token:dijflkjsige
GET /header HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8000
User-Agent: HTTPie/3.2.1
X-Token: dijflkjsige
HTTP/1.1 200 OK
content-length: 25
content-type: application/json
date: Sun, 14 Aug 2022 04:32:13 GMT
server: uvicorn
{
"X-Token": "dijflkjsige"
}