모든 개발자를 위한 HTTP 웹 기본 지식 : Header

jkky98·2024년 7월 8일
0

HTTP

목록 보기
2/8

HTTP Header

  • header-field: 헤더 필드는 다음과 같은 형식으로 작성된다:
    field-name:(OWS)field-value(OWS)
    (OWS: Optional White Space)
  • field-name은 대소문자를 구분하지 않는다.

헤더의 역할

HTTP 전송에 필요한 모든 부가 정보가 포함된다.
예를 들어:

  • 메시지 바디의 내용, 크기, 압축 정보
  • 인증 정보
  • 요청 클라이언트 및 서버 정보
  • 캐시 관리 정보 등

필요시 임의의 헤더를 추가하여 특정 요구사항을 처리할 수도 있다.


헤더의 분류와 변화

과거에는 헤더가 다음 네 가지로 분류되었다:

  • General 헤더
  • Request 헤더
  • Response 헤더
  • Entity 헤더

2014년 RFC7230~7235에서 엔티티(Entity)표현(Representation)으로 개념이 수정되었다.

  • 엔티티 헤더 → 표현 메타데이터
  • 엔티티 본문 → 표현 데이터

메시지 본문과 페이로드

  • 표현 데이터에 해당하는 부분을 메시지 본문이라 한다.
  • 이 메시지 본문을 페이로드(payload)라고 지칭한다.

표현(Representation)

표현(Representation)은 HTTP 메시지에서 데이터의 형식, 압축, 언어 등을 설명하는 메타데이터를 포함하며, 클라이언트와 서버 간 데이터 교환의 중요한 요소이다.


Content-Type

  • 표현 데이터의 형식을 설명한다.
  • 형식: Content-Type: type/subtype; parameter
    • type/subtype: 데이터 형식 (예: text/html, application/json).
    • parameter: 선택적인 추가 정보 (예: charset=UTF-8).

Content-Encoding

  • 데이터 압축 방식을 나타낸다.
  • 데이터를 전송하는 쪽에서 압축 후 Content-Encoding 헤더를 추가하며,
    데이터를 수신하는 쪽에서는 헤더 정보를 이용해 압축을 해제한다.
  • 예: gzip, deflate, identity.

Content-Language

  • 표현 데이터의 언어 종류를 지정한다.
  • 예: Content-Language: en-US.

Content-Length

  • 표현 데이터의 길이(바이트 단위)를 나타낸다.
  • Transfer-Encoding을 사용하는 경우 Content-Length를 함께 사용하면 안 된다.

자동 지원과 학습의 필요성

웹 애플리케이션 프레임워크는 일반적으로 이러한 헤더를 자동으로 처리하고 설정한다.
하지만, 자동화된 처리와 별개로, 이러한 헤더의 역할과 의미를 이해하는 것은 중요하다.
이는 디버깅, 최적화, 또는 특정 요구사항에 맞춘 설정에서 도움이 된다.

from django.shortcuts import render

def my_view(request):
    return render(request, 'my_template.html')

위의 코드에선 Content-Type: text/html; charset=utf-8를 자동으로 지정해주지만 만약 PDF 데이터 응답같은 경우는 다음과 같이 직접 지정해야할 수도 있다.

from django.http import FileResponse

def download_pdf(request):
    file_path = '/path/to/myfile.pdf'
    response = FileResponse(open(file_path, 'rb'), content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="myfile.pdf"'
    return response

협상 헤더 (Negotiation Headers)

HTTP 요청에서 사용되는 협상 헤더는 클라이언트가 선호하는 데이터 형식을 서버에 전달하기 위해 사용된다.


주요 협상 헤더

  • Accept: 클라이언트가 선호하는 미디어 타입(예: application/json, text/html).
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩(예: UTF-8).
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩(예: gzip, deflate).
  • Accept-Language: 클라이언트가 선호하는 자연 언어(예: en-US, ko).

협상 헤더의 동작

협상 헤더는 요청(Request) 시에만 사용되며, 서버는 클라이언트의 요청을 기반으로 적절한 응답을 제공한다.
예를 들어, Accept-Language를 기준으로 동작하는 경우:
1. 서버의 기본 언어 설정이 en이라면 기본적으로 영어 데이터를 응답.
2. 클라이언트가 Accept-Language: ko로 요청을 보내면, 요청의 의미는 "ko가 가능하다면 ko를 줘"가 된다.
3. 서버가 한국어 지원이 가능한 경우: 응답 데이터에 Content-Language: ko를 포함.
4. 서버가 한국어를 지원하지 않는 경우: 기본 언어인 en으로 응답.


협상 헤더는 클라이언트와 서버 간의 데이터 표현 및 언어 선택을 조율하며, 요청에 따라 서버가 적절한 콘텐츠를 제공하도록 돕는다.
서버는 협상 헤더를 참고하여 가장 적합한 응답을 제공하지만, 클라이언트 요청과 서버 설정 간 불일치 시 기본 설정값을 사용한다.

협상과 우선순위(Quality Values(q))

클라이언트는 Quality Values(q)를 사용하여 서버에 요청하는 데이터의 우선순위를 설정할 수 있다.
예를 들어, 아래와 같은 요청 메시지를 보낼 수 있다:

GET /event
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
  • q: 0에서 1 사이의 값을 사용하여 우선순위를 설정하며, 값이 클수록 높은 우선순위를 가진다.
  • 생략 시 기본값: 1이 설정된다.
    위의 예시에서 ko-KR은 기본값으로 q=1이 설정되며, 가장 높은 우선순위를 가진다.

예시 분석

  • ko-KR: 한국어(대한민국), 우선순위 1.
  • ko: 한국어(일반), 우선순위 0.9.
  • en-US: 미국 영어, 우선순위 0.8.
  • en: 일반 영어, 우선순위 0.7.

질문: ko-KR과 ko는 같은가?

  • 같다. 한국어는 대한민국에서 사용되는 언어로 지역적 구분이 없으므로 ko-KRko는 사실상 동일하다.
  • 그러나 다른 언어-지역 조합에서는 구분이 필요할 수 있다.
    예: en-US(미국 영어)와 en-GB(영국 영어).
  • 한국어를 최우선으로 설정하고 싶다면 위와 같이 ko-KRko에 각각 다른 q을 설정하여 우선순위를 지정할 수 있다.

결론

Quality Values(q)를 사용하면 클라이언트가 선호하는 데이터나 언어의 우선순위를 세밀하게 조정할 수 있다.
이를 통해 서버는 클라이언트 요청에 적합한 응답을 제공할 수 있으며, 다국어 환경에서도 효율적인 협상이 가능하다.

GET /event
Accept: text/*, text/plain, text/plain;format=flowed, */*

미디어 타입 협상에서도 우선순위가 적용되며, 기준은 구체성이다.
가장 구체적인 타입이 높은 우선순위를 가지며, 일반적인 타입이 낮은 우선순위를 가진다.

예를 들어(위의 예시 Http 메세지 참고):

  • text/plain;format=flowed: 가장 구체적이므로 1순위.
  • text/plain: 구체성이 떨어져 2순위.
  • text/*: 범용적이므로 그 다음 순위.
  • */*: 가장 일반적이므로 마지막 순위.

요청에서 타입 조건을 더 자세히 명시할수록 높은 우선순위를 갖는다.

HTTP 일반 정보 헤더

  • From:

    • 유저 에이전트의 이메일 정보를 담는다.
    • 일반적으로 잘 사용되지 않음.
  • Referer:

    • 이전 웹 페이지 주소를 나타낸다.
    • 유입 경로를 분석하는 데 사용되며 많이 활용된다.
    • 요청(Request)에서 사용.
  • User-Agent:

    • 유저 에이전트 애플리케이션의 정보를 제공한다.
    • 클라이언트의 애플리케이션 정보, 통계, 브라우저별 장애 분석에 유용하다.
    • 요청(Request)에서 사용.
  • Server:

    • 요청을 처리하는 오리진 서버의 소프트웨어 정보를 나타낸다.
    • 응답(Response)에서 사용.
  • Date:

    • 메시지가 생성된 날짜를 나타낸다.
    • 응답(Response)에서 사용되며, GMT 표준 시간대를 따른다.

특별한 정보 헤더

  • Host:

    • 요청한 호스트 정보(도메인).
    • 예: Host: www.example.com.
  • Location:

    • 페이지 리다이렉션에 사용.
    • 3xx 응답 코드와 함께 사용되며 리다이렉션 대상 URL을 지정.
  • Allow:

    • 해당 리소스에서 허용 가능한 HTTP 메서드를 나타냄.
    • 예: Allow: GET, POST.
  • Retry-After:

    • 유저 에이전트가 다음 요청까지 기다려야 하는 시간을 지정.
    • 예: Retry-After: 120 (120초 후에 재시도).

인증 관련 헤더

  • Authorization:

    • 클라이언트 인증 정보를 서버에 전달.
    • 예: Authorization: Basic xxxxxxxxxxxxxxx.
  • WWW-Authenticate:

    • 리소스 접근 시 필요한 인증 방법을 정의.
    • 401 Unauthorized 응답과 함께 사용.
    • 예:
      WWW-Authenticate: Newauth realm="apps", type=1, title="Login to \"apps\""
      WWW-Authenticate: Basic realm="simple"

쿠키

  • Set-Cookie:

    • 서버에서 클라이언트로 쿠키를 전달.
    • 응답(Response) 헤더에서 사용.
  • Cookie:

    • 클라이언트가 서버에서 받은 쿠키를 저장한 뒤,
      HTTP 요청(Request) 시 해당 쿠키를 서버로 다시 전달.

쿠키의 필요성

HTTP는 Stateless(무상태)한 프로토콜로, 각 요청 간 상태 정보를 유지하지 않는다.
이를 보완하기 위해 쿠키를 사용하여 클라이언트가 상태 정보를 보관하고, 필요한 요청마다 이를 서버에 전달한다.

예시: 로그인 인증

  1. 클라이언트가 ID와 PW를 로그인 요청 데이터로 서버에 전달.
  2. 서버는 인증 성공 후 Set-Cookie 헤더로 클라이언트에 인증 정보를 포함한 쿠키를 전달.
  3. 클라이언트는 이 쿠키를 일정 시간 저장하고,
    인증이 필요한 요청마다 Cookie 헤더에 포함해 서버로 보낸다.

즉, 쿠키는 클라이언트 입장에서 상태를 유지하는 기술로, 서버의 무상태 설계에서 필요한 인증 정보를 효과적으로 관리하는 방법이다.


모든 요청과 링크에 로그인 정보를 담기? → Nope!!

URL에 로그인 정보를 포함하는 방식은 위험하다.
1. 브라우저 히스토리 노출 위험:

  • URL은 브라우저 히스토리에 저장되므로, 민감한 로그인 정보가 남아 보안 취약점이 될 수 있다.
  • 다른 사용자가 브라우저를 통해 쉽게 접근할 가능성이 있다.
  1. 캐싱 문제:
    • 캐시 시스템은 URI를 Key로 사용하여 콘텐츠를 캐싱한다.
    • URI에 로그인 정보(쿼리 파라미터로 전달)가 포함될 경우, 캐싱된 콘텐츠에 민감 정보가 담길 수 있다.
    • 이는 불필요한 데이터 노출로 이어질 수 있다.

결론적으로, 쿠키를 사용한 안전한 상태 관리가 필요하다.

쿠키의 특성

쿠키 사용의 제한

  • 쿠키는 주로 로그인 세션 관리와 같은 최소한의 정보를 저장한다.
  • 모든 요청마다 서버로 전송되므로 네트워크 트래픽 증가를 유발한다.
  • 클라이언트 상태 유지가 필요할 경우, web storage(localStorage, sessionStorage)와 같은 대안을 사용하는 것이 효율적이다.

클라이언트에서 상태 유지에 사용되는 데이터는 민감하지 않아야 한다.
예: 개인 정보, 패스워드 등은 저장하지 말 것.


쿠키의 생명주기

  • Set-Cookie 헤더를 통해 설정된다.

    • 만료 날짜(expires):

      • 날짜를 생략하면 브라우저 종료 시 삭제된다.
      • 날짜를 지정하면 브라우저 종료 후에도 유지된다.
      • 예: Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT.
    • 유효 기간(max-age):

      • 초 단위로 지정하며, 0 또는 음수를 지정하면 쿠키가 삭제된다.
      • 예: Set-Cookie: max-age=3600 (3600초 동안 유효).

도메인 및 경로 지정

  • Domain:

    • 특정 도메인에서만 쿠키가 유효하도록 설정.
    • 예: domain=example.org → 지정된 도메인 및 서브 도메인에서 쿠키 사용.
    • Domain을 지정하지 않으면: 쿠키 생성 도메인에서만 접근 가능.
  • Path:

    • 특정 경로 및 하위 경로에서만 쿠키 접근 가능하도록 설정.
    • 예: path=/app/app 및 그 하위 경로에서만 쿠키 접근 가능.

보안 설정

  • Secure:
    • HTTPS 요청에서만 쿠키가 전송되도록 설정.
  • HttpOnly:
    • XSS 공격 방지.
    • 쿠키가 자바스크립트에서 접근 불가능하며, HTTP 요청에서만 사용되도록 제한.

쿠키는 기본적으로 최소한의 정보를 저장하며, 보안과 효율성을 위해 적절한 설정을 활용해야 한다. 민감한 정보는 저장하지 않으며, 필요에 따라 도메인, 경로, 보안 속성을 활용해 데이터를 보호한다.

XSS 공격

XSS(Cross-Site Scripting) 공격은 웹 애플리케이션의 취약점을 이용해 악성 스크립트를 삽입하여, 다른 사용자의 브라우저에서 실행되도록 하는 공격 기법이다. 이를 통해 공격자는 세션 쿠키와 같은 민감한 정보를 탈취하거나 악성 행동을 수행할 수 있다. HttpOnly 속성을 쿠키에 설정하면 자바스크립트에서 해당 쿠키에 접근할 수 없게 되어, 쿠키 탈취와 같은 XSS 공격을 효과적으로 방지할 수 있다.

profile
자바집사의 거북이 수련법

0개의 댓글