HTTP 프로토콜 2

PARK·2021년 4월 5일
0

서버 및 Node.js

목록 보기
3/7
post-thumbnail

HTTP API 설계 예시

POST 신규 자원 등록 특징

회원 관리 시스템

  • 클라이언트는 등록될 리소스의 URI를 모른다.
    회원등록 /members => POST
    POST/members

  • 서버가 새로 등록된 리소스 URI를 생성해준다.
    HTTP/1.1 201 created
    Location: /members/100

  • 컬렉션
    서버가 관리하는 리소스 디렉토리
    서버가 리소스의 URI를 생성하고 관리
    여기서 컬렉션은 /members

PUT 신규 자원 등록 특징

파일 관리 시스템

  • 클라이언트가 리소스 URI를 알고 있어야 한다.
    파일 등록 /files/{filename} => PUT
    PUT /files.start.jpg

  • 클라이언트가 직접 리소스의 URI를 지정한다.

  • 스토어
    클라이언트가 관리하는 리소스 저장소
    클라이언트가 리소스의 URI를 알고 관리
    여기서 스토어는 /files

참고: POST를 많이 사용한다.

컨트롤러, 컨트롤 URI

  • 문서, 컬렉션 스토어로 해결하기 어려운 추가 프로세스 실행
  • 동사를 직접 사용
    예) /members/{id}/delete

HTTP상태코드

클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능
1xx: 요청이되어 수신되어 처리중
2xx: 요청 정상처리
3xx: 요청을 완료하려면 추가 행동이 필요
4xx: 클라이언트오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
5xx: 서버오류, 서버가 정상 요청을 처리하지 못함

참고: 클라이언트가 인식할 수 없는 상태 코드를 반환하면 클라이언트는 상위 코드로 해석하여 처리(ex 312로 오면 3xx로 이해해서 처리)

1xx

거의 사용하지 않음

2xx

200 Ok: 요청 성공
GET메서드의 응답으로 많이 사용

201 Created: 요청성공, 새로운 리소스 생성
주로 POST로 새로운 리소스 생성 시 사용한다.
새로운 리소스는 응답의 Location 헤더 필드로 식별한다.

202 Accepted: 요청이 접수되었으나 처리가 완료되지 않음
ex) 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함

참고: 거의 사용하지 않음

204 No Content: 서버가 요청을 성공적으로 수행했지만, 응답 페이로드로 본문에 보낼 데이터가 없음
ex) 웹 문서 편집기에 save 버튼

3xx


리다이렉트: 리다이렉트 응답을 수신한 웹 브라우저는 3xx응답 결과에 Location 헤더가 있으면, 즉시 Location 위치로 이동한다. 대부분의 경우, 리다이렉션은 사용자에게는 보이지 않는데다가(빨라서), 적은 성능 저하를 일으킨다.

리다이렉트에는 몇 가지 유형이 있으며 세 가지 카테고리로 나누어진다: 영속적, 일시적, 특수 리다이렉션.

영구 리다이렉트

-리소스의 URI가 영구적으로 이동
-원래의 URI를 사용X, 검색 엔진 등에서도 변경 인지

301 Moved Permanently
-리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있다.

308 Permanently Redirect
-301과 기능은 같음
-리다이렉트시 요청 메서드와 본문 유지(POST로 보내면 POST로)

참고: 리다이렉트시 내부적으로 전달해야하는 데이터도 변경되는 경우가 많아서 301을 많이 사용한다.

일시적 리다이렉트

-리소스의 URI가 일시적으로 변경된다.
-따라서 검색엔진 등에서 URI를 변경하면 안된다.

302 Found
-리다이렉트시 요청 메서드가 GET으로 변경되고, 본문이 수정될 수 있다.

303 Temporary Redirect
-302와 기능은 같음
-리다이렉트시 요청메서드와 본문 유지

307 See Ohther
-302와 기능은 같음
-리다이렉트시 요청메서드가 GET으로 변경

참고: 303, 307 사용을 권장하지만 이미 많은 에플리케이션들이 302를 기본값으로 사용.

PRG: POST/Redirect/GET
일시적인 리다이렉션의 대표적인 예

기존에 POST로 주문 후에 새로고침하면 또 다시 POST를 요청해서 중복 주문이 발생 => PRG 리다이렉션으로 해결, POST를 Redirect해서 GET메서드로 변경한다 => 새로고침해도 중복 주문(POST) 없이 주문 화면만 얻을 수(GET) 있다

PRG의 장점
-사용성이 좋다
-서버 오류를 줄일 수 있다.

특수 리다이렉트

304 Not Modified
클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬PC에 저장된 캐시를 재사용한다.

참고: 아래 캐시에 대한 설명을 참고

4xx

-클라이언트의 요청에 잘못된 문법으로 오류발생
=> 클라이언트가 잘못된 요청, 데이터를 보내고 있기 때문에 재시도가 실패로 끝남

400 Bad Request
클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
-요청 구문, 메시지 구문
ex) 요청 파라미터가 잘못되어거나 api 스펙이 맞지 않을 때 자주 사용

401 Unautohrized
클라이언트가 해당 리소스에 대한 인증이 필요함
-인증 Authentication: 본인이 누구인지 확인 하는 과정(예를 들어, 로그인)
오류 발생 시 이 상태는 WWW-Authenticate (en-US) 헤더와 함께 전송되며, 이 헤더는 올바르게 인증하는 방법에 대한 정보를 포함하고 있음

403 Forbidden
서버가 요청을 이해는 했지만 승인을 거부함
-주로 인증 자격은 있지만, 권한이 없는 경우
인가 Authoriation가 나지 않는 경우
ex) Admin이 아닌 사용자가 Admin 리소스에 접근하는 경우

404 Not Found
요청 리소스를 찾을 수 없음
-요청 리소스가 서버에 없을 때
-해당 리소스를 숨기고 싶을 때

5xx

-서버 문제로 오류 발생
=>서버에 문제가 있기 때문에 재시도 하면 성공할 수도 있음

500 Internal Server Error
서버 내부 문제로 오류 발생
-대다수 오류를 500으로 처리

503 Service Unavailble
서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
-예측불가능한 경우가 많기 때문에 거의 볼 수 없음

HTTP 헤더

HTTP에서 표현은 요청이나 응답에서 전달할 실제 데이터를 말한다
표현은 표현 헤더와 표현 데이터로 나뉜다.
표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공한다.
표현 데이터는 메시지 본문(바디)에 해당되는 부분이다.

Content-Type

표현 데이터의 형식 설명
-미디어 타입, 문자 인코딩
-text/html, application/json 등등

Content-Encoding

표현 데이터 인코딩
-데이터를 전송하는 쪽에서 압축 후 인코딩 헤더를 추가한다.
-gzip, deflate 등등

Content-Language

표현 데이터의 언어를 표현
-ko, en-US 등등

Content-Length

-바이트 단위로 메시지 크기 표현

협상

클라이언트가 선호하는 표현 요청
-Accept: 클라이언트가 선호하는 미디어 타입 전달
-Accept-Charset: 클라이언트가 선호하는 문자 인코딩
-Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
-Accept-Language: 클라이언트가 선호하는 자연 언어

참고: 협상헤더는 요청시에만 사용한다.

협상과 우선순위

  1. Quality Values(q)값 사용
    -0~1, 클수록 우선순위
    -생략하면 1
    ex) Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0,7

  2. 구체적인 것이 우선
    ex) Accept: text/, text/plain, text/plain;format=flowed,
    우선 순위 =>
    1.text/plain;format=flowed
    2.text/plain
    3.text/

전송

Content-Length

단순 전송

Content-Encoding

압축 전송

Transfer-Encoding

분할전송

먼저 오는 도착하는 대로 사용할 수 있음
Content-Length를 보내면 안 된다. 몇 바이트씩 올 지 예상할 수 없고 chunked 안에 바이트 표기가 있기 때문이다.

Range, Content-Range

범위 전송

중간부터 다시 요청할 때 많이 사용한다.

일반 정보

From

유저 에이전트의 이메일 정보
-일반적으로 잘 사용되지 않음
-검색 엔진 같은 곳에서, 주로 사용
-요청에서 사용

Referer

이전 웹 페이지 주소
-현재 요청된 페이지의 이전 웹 페이지 주소
-A -> B로 이동하는 경우 B를 요청할 때 Referer: A 를 포함해서 요청
-Referer를 사용해서 유입 경로 분석 가능
-요청에서 사용

User-Agent

유저 에이전트 애플리케이션 정보
-클라이언트의 애플리케이션 정보(웹 브라우저 정보, 등등)
-통계 정보
-어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
-요청에서 사용

Server

요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
-origin서버: 중간 서버말고 Http응답을 해주는 최종 서버
ex) Server: Apache/2.2.22 (Debian)
-응답에서 사용

Date

메시지가 발생한 날짜와 시간
ex) Date: Tue, 15 Nov 1994 08:12:31 GMT
-응답에서 사용

특별한 정보

Host

요청한 호스트 정보(도메인)
-요청에서 필수로 사용
하나의 서버가 여러 도메인을 처리하거나 하나의 IP주소에 여러 도메인이 적용되어 있으면 요청메시지가 갈 곳을 못찾기 때문에 Host로 해당 도메인을 지정해주어야 한다.

Location

페이지 리다이렉션
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동 (리다이렉트)
-201(created)와 3xx에서 사용, 리다이렉션 하기 위한 위치를 가리킴

Allow

허용 가능한 HTTP 메서드를 나타낸다.
-응답으로 405 (Method Not Allowed)를 보낼때 포함해야하는 정보
ex) Allow: GET, HEAD, PUT (POST는 제공하지 않는다고 알림)

많이사용하지는 않음

Retry-After

유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
-503 (Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
ex) Retry-After: Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
ex) Retry-After: 120 (초단위 표기)

인증 Authorization

Authorization과 WWW-Authenticate 전달
Authorization
클라이언트 인증 정보를 서버에 전달

WWW-Authenticate
리소스 접근시 필요한 인증 방법 정의
-401 Unauthorized 응답과 함께 사용

쿠키

Http프로토콜은 무상태, 비연결 프로토콜임으로 서버가 클라이언트의 정보를 알기위해서는 클라이언트가 서버에게 방대한 양에 정보를 매번 보내야하는 문제가 있다. => 쿠키를 사용함으로써 해결한다.

기본동작

HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 클라이언트의 웹 브라우저에 전송하는 작은 데이터 조각이다. 클라이언트가 서버에 요청을 보내면 (여기서 요청은 로그인, 사용자 개인 테마 같은 것) 서버는 응답할 때 헤더 Set-Cookie 형태로 쿠키를 보낸다. 그러면 브라우저는 쿠키를 저장한다. 클라이언트가 동일한 서버에 요청을 보낸다면 브라우저는 매번 자동으로 쿠키저장소를 조회해서 헤더 Cookie형태로 쿠키를 보낸다.

-사용처: 로그인 세션 관리, 트래킹, 사용자 개인화
-쿠키 정보는 항상 서버에 전송됨, 네트워크 트래픽 추가 유발

생명주기

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

쿠키 - 도메인

Domain
-명시할 경우 명시한 문서 기준 도메인 + 서브 도메인 포함
ex) domain=example.org를 지정해서 쿠키 생성
example.org과 dev.example.org(서브 도메인)도 쿠키 접근

-생략할 경우 현재 문서 기준 도메인만 적용
ex) example.org 에서 쿠키를 생성하고 domain 지정을 생략
example.org 에서만 쿠키 접근 가능

쿠키 - 경로

Path
-일반적으로 path=/ 루트로 지정
-이 경로를 포함한 하위 경로 페이지만 쿠키 접근 가능하다.

ex) path=/home
/home -> 가능
/home/level1 -> 가능
/home/level1/level2 -> 가능
/hello -> 불가능

쿠키 - 보안

Secure, HttpOnly, SameSite
-Secure
쿠키는 http, https를 구분하지 않고 전송
Secure를 적용하면 https인 경우에만 전송한다.

-HttpOnly
XSS 공격 방지
자바스크립트에서 접근 불가(document.cookie)
HTTP 전송에만 사용

-SameSite
XSRF 공격 방지
요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

쿠키 ex) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure

캐시

웹 브라우저에서 리소스를 재사용해서 사용자의 편리함을 증가시킨다.
네트워크 트래픽을 줄이고 브라우저 로딩 속도를 높인다.

기본동작

클라이언트가 요청을 보내면 서버는 응답 메시지에 cache-control: max-age 형태로 헤더를 보낸다. 캐시는 사용자 저장공간에 저장된다. 다음에 동일한 리소스 요청이 있을 경우 저장공간을 조회해서 로드한다.

검증 헤더와 조건부 요청1

1 cache-control: max-age가 의미하는 것은 캐시 유효시간이다. 만약에 cache-control: max-age: 60으로 설정하면 해당 캐시는 60초 동안만 유효한 것이다. 60초안에 재요청을 하면 그대로 사용하고 그렇지 못하면 검증 작업을 진행한다.

2 서버는 캐시를 생성할 때 cache-control 헤더 뿐만 아니라 Last-Modified (ex: Last-Modified: 2020년 11월 10일 10:00:00)헤더도 추가시켜 생성한다. 유효시간이 지났을 때 클라이언트는 헤더 ( if-modified-since: 2020년 11월 10일 10:00:00 )를 서버로 보내 검증작업을 받는다.

3 서버는 해당 기간 동안 변경이 없다고 판단하면 HTTP/1.1 304 Not Modified 보내 저장공간에 있던 리소스를 사용해도 좋다고 응답한다(캐시 저장공간으로 리다이렉션한다). 만약에 변경이 있다면 HTTP/1.1 200 OK와 바디에 데이터를 포함해 응답한다.

4 Last-Modified를 검증 헤더, if-modified-since를 조건부 요청이라고 한다. 검증 헤더와 조건부 요청 사용하는 것은 저장되어 있던 캐시를 재활용하는 실용적인 방법이다. 그리고 304 Not Modified 메시지는 바디를 포함하지 않기 때문에 네트워크 트래픽도 줄일 수 있다.

검증 헤더와 조건부 요청2

-ETag(Entity Tag)
캐시용 데이터에 임의의 고유한 버전 이름을 생성한다.
ex) ETag: "v1.0", ETag: "a2jiodwjekjl3"

-데이터가 변경되면 이 이름을 바꾸어서 변경함(Hash를 다시 생성)
ex) ETag: "aaaaa" -> ETag: "bbbbb"

=> 메시지 헤더의 ETag만 보내서 같으면 유지, 다르면 다시 받기

검증작업과 헤더는 검증 해더와 조건부 요청 1의 3,4와 동일하다.

캐시와 조건부 헤더 요청

Cache-Control 캐시 지시어(directives)
-Cache-Control: max-age
캐시 유효 시간, 초 단위

-Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용
(원 서버는 프록시 서버에서 확인)

-Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨, (메모리에서 사용하고 최대한 빨리 삭제)

Pragma
캐시 제어
-Pragma: no-cache
HTTP 1.0 하위 호환, Cache-Control 권장

Expires
캐시 만료일 지정(하위 호환)
지금은 더 유연한 Cache-Control: max-age 권장

Froxy 캐시

Cache-Control
-Cache-Control: public
응답이 public 캐시에 저장되어도 됨

-Cache-Control: private
응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본값)

-Cache-Control: s-maxage
프록시 캐시에만 적용되는 max-age

-Age: 60 (HTTP 헤더)
오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)

확실한 캐시 무효화 응답

-Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!)
-Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨, 메모리에서 사용하고 최대한 빨리 삭제
-Cache-Control: must-revalidate
캐시 만료후 최초 조회시 원 서버에 검증해야한다. 원 서버 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout)

must-revalidate는 캐시 유효 시간이라면 캐시를 사용하는 반면에 no-cache는 항상 검증한다. no-cache는 프록시 서버와 원 서버 간에 통신 장애가 있을 때 프록시 서버로부터 데이터를 받아서 캐시하는 경우도 있다. 반면에 must-revalidate는 504(Gateway Timeout)를 발생시킨다.

-Pragma: no-cache
HTTP 1.0 하위 호환을 위해서

확실한 캐시 무효화 응답 헤더

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache

참고

리다이렉션 MDN

캐시 MDN

쿠키 MDN

모든 개발자를 위한 HTTP 웹 기본 지식- 김영한

profile
익숙한 것에 작별을 고해야한다

0개의 댓글