[HTTP 기본] 3

smj_716·2025년 4월 10일

스프링 완전 정복

목록 보기
14/16

HTTP 헤더 1 - 일반 헤더

➡️ (1) HTTP 헤더의 구조와 표현(Representation)

HTTP 헤더란?

HTTP 헤더는 요청(Request)이나 응답(Response) 메시지에 포함되어 추가적인 정보를 전달하는 역할을 한다.

🌟 헤더 분류 (RFC2616 기준)

  • General 헤더: 메시지 전체에 적용되는 헤더 (ex. Connection: close)
  • Request 헤더: 요청 정보 (ex. User-Agent : Mozilla/5.0)
  • Response 헤더: 응답 정보 (ex. Server : Apache)
  • Entity 헤더: Entity 본문(요청이나 응답에서 전달할 실제 메시지)을 해석할 수 있는 정보를 제공 → 표현 헤더로 변경(RFC723x)

표현(Header)과 표현 데이터(Representation)
HTTP/1.1 최신 표준(RFC723x)에서는 Entity 대신 Representation(표현) 개념을 사용한다.

표현 = 표현 메타데이터 + 표현 데이터(payload)

주요 표현 헤더

  • Content-Type: 미디어 타입 (ex: text/html; charset=utf-8, application/json)
  • Content-Encoding: 압축 방식 (ex: gzip, deflate)
  • Content-Language: 자연 언어 (ex: ko, en)
  • Content-Length: 바이트 길이

협상 헤더 (콘텐츠 네고시에이션)
클라이언트가 원하는 표현 데이터를 서버에 요청할 때 사용하는 Request 헤더이다.

  • Accept: 선호하는 미디어 타입
  • Accept-Encoding: 선호하는 압축 방식
  • Accept-Language: 선호하는 언어
    1. 기본 우선순위 → q값은 0~1 사이 숫자로 클수록 우선순위가 높음
    Accept-Language: ko-KR, ko;q=0더 구체적인 것이 우선.9, en-US;q=0.8, en;q=0.7
    2. 더 구체적인 것이 우선 → 같은 q값이라도 더 구체적인 표현이 우선
    Accept: text/*, text/plain, text/plain;format=flowed, */*
    3. q갑과 구체성 둘 다 고려
  • Accept-Charset: 선호하는 문자 인코딩
    브라우저 언어 설정이 ko인 경우:

전송 방식?
: 클라이언트의 협상 결과로 선택된 표현 데이터를 실제로 전송하는 방식

📌 단순 전송 📌 압축 전송

📌 분할 전송 📌 범위 전송

✅ 일반 정보

  • From: 유저 에이전트의 이메일 정보 (요청)
  • Referer: 이전 웹 페이지 주소 (요청)
  • User-Agent: 유저 에이전트 애플리케이션 정보 (요청)
  • Server: 요청을 처리하는 Origin 서버의 소프트웨어 정보 (응답)
  • Date: 메시지가 생성된 날짜 (응답)

✅ 특별한 정보

  • Host:
    • 요청한 호스트 정보(도메인)
    • 하나의 IP 주소에 여러 도메인 적용되어 있을 때 사용
  • Location:
    • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면 Location 위치로 자동 이동
    • 201 (Created): Location 값은 요청에 의해 생성된 리소스 URI
  • Allow:
    • 허용 가능한 HTTP 메서드
    • 405 (Method Not Allowed) 에서 응답에 포함해야함
  • Retry-After:
    • 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
    • 503 (Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
    • 날짜와 초단위 표기가 있음

➡️ (2) 인증

  • Authorization: 클라이언트 인증 정보를 서버에 전달
  • WWW-Authenticate: 리소스 접근시 필요한 인증 방법 정의 -> 401 Unauthorized 응답과 함께 사용

➡️ (3) 쿠키

로그인 후 다시 페이지를 접속하면 사용자의 정보가 없어서 다시 로그인을 해야한다.
그럼 모든 요청과 링크에 사용자 정보 포함해야하나❓
⚠️ 브라우저를 완전 종료하고 다시 열면..?
쿠키를 사용해서 사용자 정보를 저장하자‼️
로그인 후 받은 세션 ID나 JWT 토큰을 쿠키에 저장하여 다음 요청에 자동으로 포함돼서 로그인이 가능해진다.

위 그림처럼 모든 요청에 쿠키를 포함하면 어떨까?

⚠️ 쿠키 정보가 항상 서버에 전송되기 때문에 네트워크 트래픽 추가
최소한의 정보만 사용(세션 id, 인증 토큰)만 사용하고, 서버에 전송하지 않고 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지를 이용하자‼️

⚠️ 보안에 민감한 데이터는 저장하면 안되니 조심

📌생명주기

  • Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT 만료일이 되면 쿠키 삭제
  • Set-Cookie: max-age=3600 (3600초) 0이나 음수를 지정하면 쿠키 삭제
  • 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
  • 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지

📌도메인
domain=example.org
명시한다면 명시한 문서 기준 도메인 + 서브 도메인 포함하여 쿠키를 생성하고 생략하면 현재 문서 기준 도메인만 쿠키가 적용된다.

📌경로

  • 경로를 포함한 하위 경로 페이지만 쿠키 접근
  • 일반적으로 path=/ 루트로 지정

📌보안
Secure, HttpOnly, SameSite 등으로 쿠키 보안


2. HTTP 헤더 2 - 캐시와 조건부 요청

➡️ (1) 캐시

캐시란?

클라이언트(브라우저)가 자주 사용하는 데이터를 저장해서 다음 요청 시 네트워크 없이 빠르게 응답할 수 있도록 하는 기능이다.

⚠️ 캐시 없을 때 문제

  • 매 요청마다 서버에서 데이터를 내려받아야 함
  • 네트워크 비용 증가
  • 로딩 지연 → 사용자 경험 저하

✅ 캐시 적용 방식
Cache-Control: max-age=60
→ 응답을 받은 후 60초 동안 캐시 유지

  • 유효 시간 안: 네트워크 요청 없이 캐시에서 직접 응답
  • 유효 시간 초과: 서버에 검증 요청 후 처리

⚠️ 캐시 유효 시간이 초과하면 서버를 통해 데이터를 다시 조회하고 캐시를 갱신한다. 이때 다시 네트워크 다운로드가 발생하는 경우는 두가지이다.
🔍 서버에서 기존 데이터를 변경
🔍 서버에서 기존 데이터를 변경 X
캐시 만료 후에도 캐시 재사용 가능한 경우이다. 그렇다면 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요하다.

위 사진과 같이 데이터 수정 날짜가 같으면 바디 내용을 제외하고 304 Not Modified로 응답하여 캐시를 재사용할 수 있다. 이때 전달받은 헤더 데이터를 다시 갱신한다.

➡️ (2) 검증 헤더와 조건부 요청

✅ 검증 헤더(Validator)
: 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터

  • Last-Modified: 마지막 수정 시간
  • ETag: 고유한 해시값(버전 태그)

⚠️ 문제점

  • 1초 미만 단위로 캐시 조정 불가능
  • 데이터를 수정해서 날짜가 다르지만 실제로는 같은 데이터를 수정해서 결과가 같은 경우
  • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 (스페이스, 주석 등)

✅ 조건부 요청 (Conditional Request)
If-Modified-Since:
→ 클라이언트가 저장한 Last-Modified 값과 비교
→ 리소스가 수정되지 않았다면 304 Not Modified 반환

If-None-Match:
→ 클라이언트가 저장한 ETag 값을 전송
→ 서버가 ETag를 비교해서 같으면 캐시 사용, 다르면 새 데이터 응답
→ 서버가 캐시 제어 로직을 직접 관리

➡️ (3) 캐시 제어 헤더

🔐 Cache-Control

  • max-age=60 : 캐시 유효 시간(초)
  • must-revalidate : 캐시 만료 후 최초 조회 시 원 서버에 검증 -> 실패 시 504 오류 발생
  • no-cache : 캐시는 하지만 사용 전 서버에 검증 필요
  • no-store : 아예 저장 금지 (ex. 민감 정보)
  • public : 응답이 public 캐시에 저장
  • private : 응답이 해당 사용자만을 위한 것, private 캐시에 저장

🔐 Pragma

  • no-cache만 존재하여 잘 사용하지 X

🔐 Expires

  • 정확한 캐시 만료일을 정함
  • But, max-age를 더 권장하며 expires와 함께 사용하면 expires 무시됨

➡️ (3) 프록시 캐시

브라우저 외에도 중간 서버(프록시)가 캐시를 보관할 수 있다.
→ 전 세계 사용자에게 빠른 응답을 제공할 수 있다.

프록시 캐시와 원 서버의 네트워크 단절 상황을 살펴보자!
👉 no-cache

오류를 반환하기보다는 프록시 캐시에 저장되어있는 오래된(이전) 데이터라도 보여주자!!

👉 must-revalidate

매우 중요한 돈과 관련된 결과로 생각해보자. 만약 통장의 잔액이 이전 데이터로 뜬다면 사용자는 매우 당황할 것이다. 차라리 504 Gateway Timeout
오류를 반환하자

0개의 댓글