Network · 완벽 가이드 Ch.4 §4

HTTP 헤더 심화에 대해서 설명해주세요 (캐시, 인증, 콘텐츠 협상)

Cache-Control, ETag, Authorization, Accept 헤더의 동작 원리를 인터랙티브 시각화로 완전 정복합니다. 캐시 무효화 전략부터 보안 헤더까지 실무에서 바로 쓰는 HTTP 헤더 심화 가이드.

2026년 3월 31일 · 약 15분 읽기

Q. "HTTP 캐시 제어 헤더인 Cache-Control의 주요 디렉티브를 설명하고, 클라이언트 측 캐시 전략을 어떻게 설계하는지 말씀해주세요."

예상 꼬리질문

답변 가이드

HTTP 헤더(HTTP Header)는 요청/응답과 함께 전달하는 메타데이터 키-값 쌍으로, 캐시 제어·인증·콘텐츠 협상 등 HTTP 통신의 핵심 기능을 담당합니다. 그 중 Cache-Control 헤더는 max-age=N(N초 캐시 유지), no-cache(매번 서버 재검증), no-store(캐시 금지), public/private(공유/개인 캐시) 등의 디렉티브로 세밀하게 캐시 동작을 제어합니다.

캐시가 만료됐을 때 전체를 다시 받는 대신 ETagIf-None-Match로 조건부 요청을 보내 변경이 없으면 304 Not Modified를 받아 네트워크를 절약합니다. 정적 자산(JS/CSS)은 파일명에 콘텐츠 해시를 포함하고 immutable을 붙여 1년 캐시하고, HTML은 no-cache로 항상 재검증하는 전략이 실무 표준입니다.

인증 측면에서는 Authorization: Bearer <JWT> 패턴이 RESTful API 표준이며, 콘텐츠 협상Accept, Accept-Language, Accept-Encoding 헤더로 클라이언트가 원하는 형식을 서버에 알립니다. Vary 헤더로 CDN이 인코딩·언어별로 다른 캐시를 유지하게 하고, HSTS·CSP 같은 보안 헤더로 XSS·다운그레이드 공격을 방어합니다.

면접관이 HTTP를 물으면 보통 메서드나 상태 코드에서 멈추지만, 진짜 실력은 헤더를 얼마나 다루는지에서 드러납니다.

캐시 전략을 잘못 짜면 배포 후에도 사용자에게 이전 버전이 보이고, 인증 헤더 한 줄이 보안 취약점이 됩니다. 이 아티클에서 캐시·인증·콘텐츠 협상 헤더를 인터랙티브 시각화로 체험하며 완전히 정복해 보겠습니다.


1. Cache-Control — 캐시를 지배하는 단 하나의 헤더

꼬리질문: "no-cache와 no-store의 차이는 무엇인가요?"

캐시 제어는 Cache-Control 헤더 하나로 대부분 해결됩니다. 이 헤더의 디렉티브를 정확히 이해하면 서버 부하를 줄이면서도 사용자에게 항상 최신 콘텐츠를 제공하는 전략을 세울 수 있습니다.

헷갈리기 쉬운 no-cacheno-store의 차이가 핵심입니다. no-cache는 "캐시에 저장은 하되, 쓸 때마다 서버에 물어봐"이고, no-store는 "아예 저장하지 마"입니다.

디렉티브를 클릭하면 "캐시에 저장되는가? / 서버 검증이 필요한가? / CDN에 저장 가능한가?" 세 가지 질문에 대한 답을 확인할 수 있습니다.

Cache-Control 디렉티브 탐색기

디렉티브를 클릭하면 동작 방식을 확인할 수 있습니다

no-cacheno-store의 차이를 클릭해서 확인해보세요!

많은 개발자들이 이 둘을 혼동합니다


2. 캐시 재검증 — ETag로 304를 이끌어내는 법

꼬리질문: "ETag는 어떻게 캐시 재검증에 사용되나요?"

캐시가 만료됐다고 무조건 전체 응답을 다시 받으면 낭비입니다. ETag를 이용하면 "내가 가진 버전과 같아?" 하나만 물어보고, 변경이 없으면 304 Not Modified(바디 없음)로 응답받아 대역폭을 크게 절약합니다.

ETag는 리소스의 지문(fingerprint)입니다. 서버가 응답에 ETag: "abc123"을 내려주면, 클라이언트는 다음 요청 시 If-None-Match: "abc123"을 보내 재검증합니다.

"콘텐츠 변경" 토글로 서버 리소스 변경 여부를 선택하고, 재검증 요청이 어떻게 달라지는지 확인해 보세요.

ETag 캐시 재검증 흐름

콘텐츠 변경 여부를 선택하고 재검증 요청을 시뮬레이션하세요

1단계: 최초 요청
클라이언트 →
GET /article

최초 요청 — ETag 없음

← 서버
200 OK + ETag: "abc123"

서버가 전체 응답(120KB)과 함께 ETag를 내려줍니다

2단계: 재검증 요청
서버 콘텐츠 변경:

Last-Modified vs ETag 비교

Last-Modified
  • • HTTP/1.0 호환
  • • 1초 단위 정밀도
  • • 내용 같아도 시간 변경 시 재다운로드
ETag (권장)
  • • 콘텐츠 해시 기반
  • • 밀리초 미만 변경도 감지
  • • 두 헤더 모두 있으면 ETag 우선

3. 캐시 전략 패턴 — 콘텐츠 유형별 최적 설정

꼬리질문: "정적 자산과 HTML에 각각 어떤 캐시 전략을 쓰나요?"

캐시 전략은 콘텐츠 유형마다 달라야 합니다. 정적 자산(JS/CSS)은 파일명에 콘텐츠 해시를 넣고 1년을 캐시해도 되지만, HTML은 항상 최신 버전이어야 합니다.

실무에서 가장 많이 저지르는 실수는 모든 리소스에 동일한 max-age를 적용하거나, 캐시 무효화 수단 없이 긴 만료 시간을 설정하는 것입니다.

각 행을 클릭하면 해당 전략을 선택한 이유와 실제 HTTP 헤더 코드를 확인할 수 있습니다.

콘텐츠 유형별 캐시 전략

행을 클릭하면 이 전략을 선택한 이유와 코드 예시를 확인할 수 있습니다

콘텐츠 유형Cache-Control캐시 위치무효화 방법
📦정적 자산 (JS/CSS/이미지)
public, max-age=31536000, immutable브라우저 + CDN파일명 변경 (content hash)
🌐HTML 페이지
no-cache브라우저만즉시 (매 요청 검증)
🔌API 응답 (개인화)
private, max-age=60브라우저만max-age 만료 대기
🔒민감 데이터 (결제/개인정보)
no-store저장 안 함해당 없음

SPA 최적 전략: JS/CSS는 1년 캐시 + HTML은 no-cache — 해시 파일명으로 무효화 + HTML로 항상 최신 파일 참조


4. HTTP 인증 — Authorization 헤더 완전 해부

꼬리질문: "HTTP 인증 헤더의 Bearer 스킴은 어떻게 동작하나요?"

HTTP는 stateless이므로 매 요청에 인증 정보를 담아야 합니다. Authorization 헤더가 그 역할을 합니다. 서버가 401 Unauthorized와 함께 WWW-Authenticate 헤더로 스킴을 알려주면, 클라이언트가 해당 스킴에 맞는 자격증명을 담아 재요청합니다.

현대 API에서 가장 널리 쓰이는 스킴은 Bearer입니다. Authorization: Bearer <JWT> 형태로 토큰을 전송하며, OAuth 2.0 표준을 따릅니다.

스킴 탭을 전환하며 Basic, Bearer, API Key의 헤더 형식과 보안 수준을 비교해 보세요.

HTTP 인증 흐름 & 스킴 비교

스킴을 선택하면 인증 헤더 형식과 보안 수준을 확인할 수 있습니다

RFC 7235 표준 인증 흐름

1단계
GET /protected
보호된 리소스 요청
2단계
401 Unauthorized
WWW-Authenticate: Bearer
3단계
GET /protected
Authorization: Bearer <token>
4단계
200 OK
인증 성공, 리소스 반환
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJleHAiOjE3MDAwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT 구조 분해
Header
{"alg":"HS256","typ":"JWT"}
Payload
{"userId":"123","exp":1700000000}
Signature
HMACSHA256(base64(header)+"."+base64(payload), secret)

Header.Payload.Signature 세 부분을 Base64url로 인코딩 후 점(.)으로 연결합니다.

보안 수준
높음 (단기 만료 권장)
주요 사용 사례

RESTful API, OAuth 2.0, 마이크로서비스 인증


5. 콘텐츠 협상 — Accept 헤더로 원하는 형식 요청하기

꼬리질문: "콘텐츠 협상이 무엇이고 어떤 헤더를 사용하나요?"

콘텐츠 협상(Content Negotiation)은 클라이언트가 원하는 형식을 서버에게 알리고, 서버가 가장 적합한 형식으로 응답하는 메커니즘입니다. Accept(타입), Accept-Language(언어), Accept-Encoding(압축) 세 헤더가 핵심입니다.

q 파라미터(quality factor, 0~1)로 우선순위를 표현합니다. Accept: text/html, application/json;q=0.9는 "HTML이 최선이지만 JSON도 괜찮다"는 의미입니다.

클라이언트·서버 지원 항목을 직접 설정하며 협상 결과가 어떻게 달라지는지 시뮬레이션해 보세요.

콘텐츠 협상(Content Negotiation) 시뮬레이터

클라이언트·서버 지원 항목을 설정하면 협상 결과를 확인할 수 있습니다

클라이언트 Accept 헤더

Accept: text/html, application/json;q=0.9

서버 지원 포맷

200 OK — HTML

클라이언트 우선순위 1위 중 서버가 지원하는 HTML 선택

Content-Type: text/html

6. 보안 헤더 — 한 줄로 방어하는 XSS·Clickjacking·다운그레이드

꼬리질문: "CORS 헤더에서 Preflight 요청이 발생하는 조건은?"

보안 헤더는 브라우저에게 보안 정책을 지시하는 응답 헤더입니다. 서버 코드 변경 없이 헤더 한 줄로 주요 공격 벡터를 차단할 수 있습니다.

가장 중요한 세 가지는 HSTS(HTTPS 강제), CSP(스크립트 출처 제한), X-Content-Type-Options(MIME 스니핑 방지)입니다.

헤더를 ON/OFF하며 각 헤더가 방어하는 공격 유형이 어떻게 달라지는지 확인해 보세요.

보안 헤더 체크리스트

헤더를 ON/OFF하면 방어되는 공격이 달라집니다

응답 헤더 설정

공격 방어 현황

XSS (스크립트 삽입)방어됨
Clickjacking방어됨
프로토콜 다운그레이드방어됨
MIME 타입 스니핑방어됨
무단 교차 출처 접근방어됨

보안 점수: 5 / 5


자주 발생하는 문제

실무와 면접에서 자주 만나는 HTTP 헤더 관련 함정을 정리했습니다.


면접 체크리스트

이 항목들을 자신 있게 설명할 수 있다면 HTTP 헤더 심화 질문은 준비 완료입니다.

  • - Cache-Control: no-cache(저장O, 검증필요)와 no-store(저장X)의 차이. public/private으로 CDN 저장 제어
  • - ETag + If-None-Match: 재검증 요청으로 304 응답 유도 → 대역폭 99% 절약. Last-Modified보다 정밀
  • - 캐시 전략: JS/CSS는 content hash + immutable(1년), HTML은 no-cache + ETag 재검증
  • - Authorization: Bearer 스킴 = RFC 7235 표준. WWW-Authenticate → 401 → Authorization 흐름
  • - 콘텐츠 협상: Accept/Accept-Encoding/Accept-Language + q파라미터. Vary로 CDN 캐시 분리
  • - 보안 헤더: HSTS(HTTPS 강제), CSP(XSS 방어), X-Frame-Options(Clickjacking), X-Content-Type-Options(MIME 스니핑 방지)

더 알아볼 주제

  • - HTTP/2 헤더 압축 (HPACK) — 헤더 오버헤드 감소 메커니즘
  • - Fetch Metadata Request Headers (Sec-Fetch-*) — 최신 보안 헤더
  • - Permissions Policy — 브라우저 기능 접근 제어

퀴즈로 확인하기

배운 개념을 실제 시나리오에 적용해 보세요.

Quiz 1

민감 데이터를 캐시에서 완전히 차단하려면?

결제 완료 페이지 응답에 사용자의 카드 마지막 4자리가 포함됩니다.
이 페이지가 브라우저 캐시나 CDN 어디에도 저장되지 않도록 해야 합니다.
어떤 Cache-Control 설정이 적합한가요?
Quiz 2

ETag가 일치할 때 서버의 응답은?

클라이언트가 If-None-Match: "v2.1" 헤더와 함께 GET 요청을 보냈습니다.
서버의 현재 리소스 ETag도 "v2.1"입니다.
서버는 어떤 응답을 반환하나요?
Quiz 3

CDN이 Brotli와 gzip 압축 응답을 각각 캐시하려면?

서버가 Accept-Encoding: br 요청에는 Brotli로,
Accept-Encoding: gzip 요청에는 gzip으로 응답합니다.
CDN이 두 버전을 별도 캐시로 관리하게 하려면 어떤 헤더가 필요한가요?
Quiz 4

쿠키를 포함한 CORS 요청이 실패하는 이유는?

fetch('https://api.example.com/user', { credentials: 'include' })로 요청을 보냈더니
CORS 에러가 발생했습니다.
서버 응답은 아래와 같았습니다:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Quiz 5

SPA의 정적 자산과 index.html에 적합한 캐시 전략은?

React SPA 배포 시 Webpack이 main.a3f4c9.js처럼
파일명에 해시를 자동으로 포함합니다.
index.html은 이 해시된 JS 파일을 참조합니다.
각 파일에 어떤 Cache-Control을 설정해야 할까요?

추가 학습 자료를 공유합니다.


의견을 들려주세요

서비스 개선에 큰 도움이 됩니다. 익명으로 자유롭게 남겨주세요.

0 / 1000