HTTP & HTTPS
멱등성 · 캐시 헤더 · TLS 핸드셰이크 · HTTP/1.1 vs HTTP/2
웹 통신의 기반 — HTTP 메서드 특성부터 HTTPS 암호화 원리, HTTP/2 성능 개선까지
01 HTTP란? — 구조와 특성
HTTP(HyperText Transfer Protocol)는 클라이언트와 서버 간에 데이터를 주고받기 위한 애플리케이션 계층 프로토콜입니다. TCP/IP 위에서 동작하며 기본 포트는 80(HTTP), 443(HTTPS)입니다.
요청-응답 후 연결을 끊습니다. 서버 자원을 효율적으로 사용할 수 있지만 매 요청마다 연결 비용이 발생합니다. HTTP/1.1의 Keep-Alive, HTTP/2의 멀티플렉싱으로 개선됩니다.
서버는 이전 요청의 상태를 기억하지 않습니다. 서버 확장(스케일 아웃)이 쉬워지지만 상태 유지가 필요한 경우 쿠키·세션·JWT 등으로 해결해야 합니다.
HTTP 메시지 구조
/* HTTP 요청 메시지 */
POST /members HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJ...
{
"name": "현수",
"age": 28
}/* HTTP 응답 메시지 */
HTTP/1.1 201 Created
Content-Type: application/json
Location: /members/1
Cache-Control: no-cache
{
"id": 1,
"name": "현수"
}02 HTTP 메서드 — 안전성 · 멱등성 · 캐시 가능성
HTTP 메서드를 제대로 이해하려면 세 가지 특성을 알아야 합니다.
서버의 상태를 변경하지 않는 메서드. 읽기 전용 작업. GET, HEAD, OPTIONS
같은 요청을 여러 번 보내도 결과가 동일한 메서드. 재시도 안전 여부의 기준.
응답을 캐시에 저장할 수 있는 메서드. GET, HEAD, POST(일부)
| 메서드 | 용도 | 안전성 | 멱등성 | 캐시 가능 |
|---|---|---|---|---|
GET |
리소스 조회 | ✅ | ✅ | ✅ |
POST |
리소스 생성, 프로세스 처리 | ❌ | ❌ | △ |
PUT |
리소스 전체 교체 (없으면 생성) | ❌ | ✅ | ❌ |
PATCH |
리소스 부분 수정 | ❌ | ❌ (설계에 따라) | ❌ |
DELETE |
리소스 삭제 | ❌ | ✅ | ❌ |
네트워크 오류로 응답을 못 받았을 때 재시도 안전 여부가 멱등성으로 결정됩니다. GET/PUT/DELETE는 멱등성이 있어 재시도해도 안전합니다. POST는 멱등성이 없어 재시도하면 중복 생성이 발생할 수 있습니다.
DELETE /members/1을 두 번 보내면 첫 번째는 삭제, 두 번째는 404지만 최종 결과(리소스 없음)는 동일하므로 멱등합니다.PUT vs PATCH 차이
// 기존 회원: { "name": "현수", "age": 28, "email": "dev@test.com" }
// PUT — 전체 교체 (보내지 않은 필드는 null/기본값으로 덮어씀)
PUT /members/1
{ "name": "현수2" }
// 결과: { "name": "현수2", "age": null, "email": null } ← 다른 필드 사라짐!
// PATCH — 부분 수정 (보낸 필드만 변경)
PATCH /members/1
{ "name": "현수2" }
// 결과: { "name": "현수2", "age": 28, "email": "dev@test.com" } ← 나머지 유지HTTP03 HTTP 상태코드
| 분류 | 주요 코드 | 의미 |
|---|---|---|
| 2xx 성공 | 200 OK · 201 Created · 204 No Content |
요청 성공. 201은 자원 생성, 204는 응답 바디 없음(DELETE 등) |
| 3xx 리다이렉션 | 301 Moved Permanently · 302 Found · 304 Not Modified |
301은 영구 이동(URL 변경), 304는 캐시 유효(바디 없이 헤더만) |
| 4xx 클라이언트 오류 | 400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found · 409 Conflict |
클라이언트 잘못. 401은 인증 필요, 403은 권한 없음(인증은 됐으나) |
| 5xx 서버 오류 | 500 Internal Server Error · 502 Bad Gateway · 503 Service Unavailable |
서버 잘못. 503은 서버 과부하/점검 중 |
401 Unauthorized — 인증이 안 된 상태입니다. "로그인하세요." 이름은 Unauthorized이지만 실제로는 인증(Authentication) 실패입니다.
403 Forbidden — 인증은 됐지만 권한이 없는 상태입니다. "로그인은 했지만 접근 권한이 없습니다." 즉 인가(Authorization) 실패입니다.
04 HTTP 헤더 — 캐시 제어
캐시는 동일한 요청에 대해 서버까지 가지 않고 저장된 응답을 재사용해 성능을 높이고 서버 부하를 줄이는 기술입니다.
주요 캐시 헤더
/* Cache-Control 지시어 */
Cache-Control: max-age=3600 // 3600초(1시간) 동안 캐시 유효
Cache-Control: no-cache // 캐시 저장은 하되, 사용 전 서버 검증 필수
Cache-Control: no-store // 캐시 저장 자체를 금지 (민감 정보)
Cache-Control: must-revalidate // 만료 후 반드시 서버 재검증
Cache-Control: public // 공유 캐시(CDN, 프록시)에도 저장 가능
Cache-Control: private // 브라우저 캐시에만 저장 (개인 데이터)
/* 조건부 요청 — 캐시 검증 */
// 서버 응답 시
ETag: "abc123" // 리소스 버전 식별자 (해시값)
Last-Modified: Wed, 01 Jan 2025 ... // 마지막 수정 시간
// 클라이언트 재요청 시 (캐시 검증)
If-None-Match: "abc123" // ETag가 같으면 → 304 Not Modified (바디 없음)
If-Modified-Since: Wed, 01 Jan ... // 변경 없으면 → 304 Not ModifiedHTTP캐시 동작 흐름
변경 있으면 200
05 HTTPS — TLS 핸드셰이크
HTTPS는 HTTP에 TLS(Transport Layer Security) 암호화를 추가한 프로토콜입니다. 데이터 도청·위변조 방지, 서버 신원 확인을 제공합니다.
TLS 1.3 핸드셰이크 흐름
비대칭키(RSA/ECDHE)는 보안성은 높지만 연산 비용이 큽니다. 대칭키(AES)는 빠르지만 키를 안전하게 공유하기 어렵습니다. TLS는 핸드셰이크 단계에서 비대칭키로 세션 키(대칭키)를 안전하게 교환하고, 이후 실제 데이터 통신은 빠른 대칭키로 암호화합니다. 둘의 장점만 취한 방식입니다.
06 HTTP/1.1 vs HTTP/2 vs HTTP/3
| 특성 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 전송 프로토콜 | TCP | TCP | QUIC (UDP 기반) |
| 멀티플렉싱 | ❌ HOL 블로킹 발생 | ✅ 하나의 TCP로 병렬 | ✅ 스트림별 독립 전송 |
| 헤더 압축 | ❌ 없음 (매 요청 반복) | ✅ HPACK 압축 | ✅ QPACK 압축 |
| 서버 푸시 | ❌ 없음 | ✅ 지원 | ✅ 지원 |
| 연결 수립 | 3-way handshake | 3-way + TLS handshake | 0-RTT (첫 연결 1-RTT) |
HTTP/1.1의 문제 — HOL 블로킹
// HTTP/1.1 — 요청을 순서대로 처리 (HOL 블로킹)
// 커넥션 1: 요청1 ----완료---- 요청2 ----완료---- 요청3
// 커넥션 2: 요청4 ----완료---- 요청5
// → 브라우저가 6개 정도 병렬 커넥션을 열어 우회 (비효율적)
// HTTP/2 — 하나의 커넥션으로 멀티플렉싱
// 커넥션 1 (스트림 1): 요청1 ========
// 커넥션 1 (스트림 2): 요청2 =====
// 커넥션 1 (스트림 3): 요청3 =======
// → 하나의 TCP 커넥션으로 동시 처리
// 단, TCP 레벨 HOL은 여전히 존재 (패킷 손실 시 전체 블로킹)
// HTTP/3 (QUIC) — 스트림별 독립 전송
// 패킷 손실이 발생해도 해당 스트림만 영향, 나머지는 정상 동작HTTP07 REST API 설계 원칙
REST(Representational State Transfer)는 HTTP를 잘 활용하기 위한 아키텍처 스타일입니다. URI는 리소스를 표현하고, HTTP 메서드로 행위를 표현합니다.
// ❌ 나쁜 설계 — 동사 사용, 행위가 URI에 포함
GET /getMembers
POST /createMember
GET /deleteMember?id=1
POST /member/update
// ✅ 좋은 설계 — 명사(리소스) + HTTP 메서드로 행위 표현
GET /members // 회원 목록 조회
POST /members // 회원 생성
GET /members/{id} // 특정 회원 조회
PUT /members/{id} // 회원 전체 수정
PATCH /members/{id} // 회원 부분 수정
DELETE /members/{id} // 회원 삭제
// 계층 관계 표현
GET /members/{id}/orders // 특정 회원의 주문 목록
GET /members/{id}/orders/{oid} // 특정 회원의 특정 주문
// 컨트롤 URI — 동사가 꼭 필요한 경우 (행위 자체가 리소스)
POST /members/{id}/follow // 팔로우
POST /orders/{id}/cancel // 주문 취소
POST /members/{id}/send-email // 이메일 발송HTTP- 소문자 사용 (
/membersO,/MembersX) - 하이픈(-) 사용 (
/order-itemsO, 언더스코어 X) - 끝에 슬래시(/) 사용 금지
- 파일 확장자 포함 금지 (
.jsonX)
- 생성 성공 →
201 Created+Location - 삭제/수정 성공 →
200or204 - 모든 에러를 200으로 반환 금지
- 에러 바디에 상세 코드 포함
08 CORS — 교차 출처 리소스 공유
CORS(Cross-Origin Resource Sharing)는 브라우저의 동일 출처 정책(SOP)을 완화해 다른 출처의 리소스를 안전하게 요청할 수 있도록 하는 메커니즘입니다. 출처는 프로토콜 + 호스트 + 포트가 모두 같아야 동일 출처입니다.
// Spring Boot에서 CORS 설정
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://frontend.example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH")
.allowedHeaders("*")
.allowCredentials(true) // 쿠키·인증 헤더 허용
.maxAge(3600); // Preflight 캐시 시간(초)
}
}
// 또는 컨트롤러/메서드 단위로 설정
@CrossOrigin(origins = "https://frontend.example.com")
@RestController
public class MemberController { ... }JavaPOST, PUT, DELETE 같은 단순 요청이 아닌 경우, 브라우저는 실제 요청 전에 OPTIONS 메서드로 서버가 해당 요청을 허용하는지 먼저 확인합니다. 서버가 허용 응답을 주면 실제 요청을 보냅니다. maxAge로 Preflight 결과를 캐시해 요청 수를 줄일 수 있습니다.09 면접 예상 질문
Q1. HTTP의 비연결성과 무상태성을 설명하세요.
Q2. GET과 POST의 차이점, 그리고 멱등성이란?
Q3. HTTPS의 동작 원리를 설명하세요.
Q4. HTTP/1.1과 HTTP/2의 차이점은?
Q5. CORS란 무엇이고 어떻게 해결하나요?
WebMvcConfigurer의 addCorsMappings로 허용 출처·메서드·헤더를 설정하거나, @CrossOrigin 어노테이션을 컨트롤러에 붙여 해결합니다. Spring Security를 사용하면 Security 필터 체인에도 CORS 설정이 필요합니다.- HTTP 특성 — 비연결성(요청 후 연결 해제) + 무상태성(서버가 이전 상태 기억 안 함)
- 멱등성 — GET·PUT·DELETE는 멱등, POST·PATCH는 비멱등. 네트워크 오류 시 재시도 안전 여부
- 401 vs 403 — 401은 인증 실패(로그인 필요), 403은 인가 실패(권한 없음)
- 캐시 헤더 — Cache-Control로 캐시 정책 설정, ETag/If-None-Match로 조건부 요청 → 304 최적화
- HTTPS/TLS — 핸드셰이크 시 비대칭키로 세션 키 교환, 이후 AES 대칭키로 빠른 암호화
- HTTP/2 — 멀티플렉싱(HOL 블로킹 개선) + HPACK 헤더 압축 + 서버 푸시
- REST API — URI는 명사(리소스), 행위는 HTTP 메서드로. 적절한 상태코드 사용
'스프링' 카테고리의 다른 글
| Spring Bean 생명주기 (0) | 2026.04.27 |
|---|---|
| Spring MVC 동작 원리 (0) | 2026.04.22 |
| 예외 처리 전략 @ControllerAdvice · @ExceptionHandler · 공통 에러 응답 설계 (1) | 2026.04.20 |
| JPQL & QueryDSL객체지향 쿼리부터 동적 쿼리까지 (1) | 2026.04.17 |
| @Transactional 동작 원리 / AOP 프록시 · self-invocation · readOnly 최적화 (0) | 2026.04.16 |