HTTP 요청 분석하기 - 2

임혁진·2023년 12월 17일
0

네트워크

목록 보기
4/5

섹션2 컨텐츠 협상~ CORS

컨텐츠 협상과 MIME 타입

HTTP요청은 Header와 Body(본문, Content, Payload)로 구성되어있다.

주의사항

쿠키에 한글을 사용하는 실수를 자주 한다. 한글을 사용하기 전에는 encodeURIComponent 함수를 사용하여 인코딩 후 사용한다.

HTTP Header

  • HTTP 헤더는 Key: Value 의 형식으로 요소가 들어있다.
  • 헤더의 키는 한글을 사용할 수 없다.(한글 데이터는 인코딩한다)
  • 값에는 특정 형식의 데이터를 나타내는 MIME 타입이 존재

MIME 타입

  • MIME 타입은 데이터의 형식을 지정하는 표준 방식으로, 일반적으로 대분류/확장자 형식으로 나타낸다.
  • 예를 들어 image/png, image/jpeg, application/json 처럼 나타낸다.

컨텐츠 협상 헤더

Accept~ 는 서버 주도 협상으로 클라이언트가 가능한 것들을 제시하면 서버가 주도해서 원하는 데이터 타입으로 지정해서 보내준다.

  • Accept: 클라이언트가 처리할 수 있는 타입
  • Accept-Encoding: 클라이언트가 지원하는 압축 방식(ex br, gzip)

Accept-Language: 클라이언트가 선호하는 언어를 ISO 언어 코드로 지정한다.

Accept-Charset: 클라이언트가 지원하는 문자 인코딩 (utf-8, ascii, euc-kr)

HTTP 응답 헤더

  • Content-Type: 요청의 Accept처럼 MIME 타입으로 나타내며 현재 보내준 컨텐츠의 타입을 나타낸다.(서버 주도 협상)

  • Content-Language, Content-Encoding: 응답의 언어와 압축 방식

  • Connection: keep-alive
    목적: HTTP/1.1에서는 기본적으로 Connection: keep-alive가 설정되어 있다.
    동작 원리: TCP 연결을 수립하는 데 필요한 시간과 리소스를 절약하기 위해, 연결을 단기간(기본적으로 약 5초) 유지해 여러 HTTP 요청과 응답이 동일한 TCP 연결을 재사용한다.

  • Date 헤더: HTTP 메시지가 생성된 정확한 날짜와 시간을 나타낸다. 캐시의 신선도를 파악하는데 사용된다.

  • Content-Encoding: 응답 본문이 어떻게 인코딩되었는지( gzip, compress, deflate)를 나타낸다.

  • Transfer-Encoding: chunked: 응답 본문이 여러 개의 청크로 나누어져서 전송됨. 동적으로 생성되는 컨텐츠의 크기를 알지 못해도 사용할 수 있는 장점이 있다.

Authorization 헤더

Basic: 사용자 이름과 비밀번호를 :로 연결하고 Base64로 인코딩
Bearer: 일반적으로 OAuth 2.0과 함께 사용되며, JWT 같은 토큰을 제공한다.
Digest

응답에 따라 필수적인 헤더

405 Method Not Allowed: 서버가 지원하지 않는 HTTP 메서드에 대한 응답이다. 이 경우 Allow 헤더를 통해 지원되는 메서드를 알려준다.

503 Service Unavailable: 서비스가 사용 불가능한 상태로 Retry-After 헤더를 사용하여 서비스가 다시 가능한 시간을 알려준다.

보안 관련 헤더

Referer: 이 헤더는 사용자가 이전에 방문한 페이지의 주소를 나타낸다. Referrer-Policy를 통해 추가적인 제약을 걸 수 있다.

Content-Security-Policy: 개인정보 유출을 방지

커스텀 헤더

임의로 커스텀 헤더를 부착할 수 있는데, 이를 기존 헤더와 구분하기 위해서 주로 X-로 시작하는 헤더를 제공한다.

쿠키

HTTP 는 stateless 즉 이전에 보낸 클라이언트의 정보를 확인할 수 없다. 이 한계를 극복하기 위해 서버는 클라이언트에 Set-cookie 헤더를 통해 key:value형태의 데이터를 전달한다. 이렇게 전달된 쿠키는 다시 클라이언트가 서버에 요청을 보낼 때 요청에 담아서 보내며 state처럼 동작한다.

쿠키 속성

  • Expires/Max-Age: 쿠키의 유효 기간
    Expires는 특정 시간을, Max-Age는 초 단위의 시간을 지정한다. 세션 쿠키는 브라우저가 종료되면 사라진다.

  • Domain/Path: 쿠키가 전송될 수 있는 도메인과 경로를 지정한다. 서브 도메인으로의 전송은 가능하지만, 메인 도메인에서 서브 도메인으로의 전송은 불가능하다.

  • Secure: 이 속성이 설정된 쿠키는 HTTPS 프로토콜을 통해서만 전송 가능하다.

  • HttpOnly: JavaScript를 통한 쿠키의 접근을 제한한다.

  • SameSite: 타 사이트 요청과 관련된 쿠키의 전송을 관리한다. Lax는 일부 타 사이트 요청에서 쿠키를 허용, Strict는 같은 사이트에서만 쿠키 전송을 허용, None은 모든 크로스 사이트 요청에서 쿠키를 허용한다.

캐시

HTTP 캐시는 서버 부하를 줄이고 로딩 속도를 증가시킨다.

  • 서버로부터의 응답이 캐시되기 전에, Cache-Control 헤더를 통해 캐시의 동작을 정의한다.

  • Cache Hit: 요청된 리소스가 캐시에 존재하고 신선한 경우. 서버에 다시 요청할 필요 없이 캐시된 데이터를 사용한다.

  • Cache Miss: 요청된 리소스가 캐시에 존재하지 않거나 유효하지 않은 경우. 새로운 데이터를 서버로부터 요청한다.

캐시 신선도

  • Cache-Control의 max-age: 캐시를 얼마나 오래 유지할 것인지 결정.

  • 304 Not Modified: 클라이언트의 캐시가 최신 상태일 때, 서버는 304 Not Modified 응답을 보내어 캐시된 데이터를 재사용한다.

  • 200 OK: 캐시가 오래되었거나 존재하지 않는 경우, 서버는 새로운 데이터와 함께 200 OK 응답을 보낸다.

Cache-Control 옵션

  • no-cache: 캐시 저장은 가능하지만, 사용 전에 항상 신선도를 검사한다. (no-store와 혼동 주의)

  • no-store: 캐시를 저장하지 않는다.

  • must-revalidate: 캐시의 유효기간이 지나면 반드시 신선도를 검사한다.

  • private/public: private은 개인 캐시 저장소에만 저장, public은 공유 캐시에 저장합니다. 공유 캐시는 다른 사용자가 접근할 때도 가져갈 수 있는 캐시다.

  • stale-while-revalidate: 오래된 캐시를 사용하면서 백그라운드에서 새 데이터를 가져온다.

stale-if-error: 서버 오류 시에도 오래된 캐시를 사용한다.

캐시 신선도 검사 메커니즘

  • ETag: 리소스의 고유 식별자. 리소스가 변경될 때마다 ETag 값이 변경된다. If-Match, If-None-Match 헤더를 사용하여 리소스의 신선도를 확인한다.

  • Last-Modified/If-Modified-Since: 리소스의 마지막 수정 시간을 기반으로 신선도를 검사한다.

CORS

기본적으로 웹 페이지는 자신과 같은 오리진(도메인)의 서버로만 HTTP 요청을 보낼 수 있다. CORS는 브라우저에서 클라이언트를 보호하기 위한 정책으로 다른 도메인의 리소스를 요청할 때 적용된다.

  • Origin 헤더: 브라우저에서 CORS정책을 적용해 요청을 할 때 헤더에 Origin 헤더를 부착하여 자신의 도메인을 알린다.

  • Access-Control-Allow-Origin: 서버에서 Origin을 포함한 헤더를 받으면 이 헤더를 이용해 사용 가능한 도메인을 알려준다.

  • CORS 에러: 브라우저는 Access-Control-Allow-Origin 헤더가 없거나 현재 오리진을 허용하지 않는 경우, 응답을 차단한다.

  • simple request와 preflighted request: 간단한 메서드 (GET, HEAD, POST)와 지정 헤더와 Content Type에 대해서 simple request의 조건을 만족하면 preflight를 발생하지 않고 바로 요청을 보낸다. 조건을 만족하지 않는다면 브라우저는 우선 preflighted request를 먼저 보내 서버에 해당 메서드가 가능한지 확인한 후 요청을 보낸다.

  • Credentials: access-control-allow-credentials: true를 설정하면 쿠키와 같은 인증 정보도 함께 전송할 수 있다.

CORS 해결 방법

  • 서버 설정 변경: 가장 좋은 방법은 CORS 정책을 변경하여 특정 오리진에서의 요청을 허용하도록 설정하는 것이 좋다.
  • 프록시 서버: 브라우저는 같은 오리진으로의 요청에 대해서는 CORS 정책을 사용하지 않는다. 따라서 프록시 서버(예: webpack-dev-server)를 사용하여 CORS 문제를 해결할 수 있다.
profile
TIL과 알고리즘

0개의 댓글