- HTTP/1.1, HTTP/2는 TCP 기반 프로토콜
- HTTP/3는 UDP 기반 프로토콜
- 만약 TCP / UDP 내용이 헷갈린다면 아래 포스팅을 참고하자.
TCP / UDP 참고링크
클라이언트 서버 구조 (Request Response 구조)
무상태 프로토콜 (Stateless),
- 서버가 클라이언트의 상태를 보존하지 않는다.
- 장점: 서버 확장성이 높음 (스케일 아웃),
요청할 때 이미 필요한 데이터를 다 담아서 보내기 때문에 아무 응답 서버를 호출해도 되기 때문에 즉, 응답 서버를 쉽게 바꿀 수 있기 때문에 무한한 서버 증설이 가능하다.- 단점: 클라이언트가 추가 데이터를 전송해야함
- 한계
로그인이 필요 없는 단순한 서비스 소개 화면 같은 경우엔 무상태로 설계할 수 있지만
로그인이 필요한 서비스라면 유저의 상태를 유지해야 되기 때문에 브라우저 쿠키, 서버 세션, 토큰 등을 이용해 상태를 유지해야한다.
비연결성 (Connectionless)
TCP/IP의 경우 기본적으로 연결을 유지하는데 이럴 경우 서버의 자원이 계속 소모가 된다.
- 비연결성을 가지는 HTTP에서는 실제로 요청을 주고받을 때만 연결을 유지하고 응답을 주고 나면 TCP/IP 연결을 끊는다.
이를 통해 최소한의 자원으로 서버 유지를 가능하게 한다.
- HTTP 1.0 기준으로, HTTP는 연결을 유지하지 않는 모델이다.
트래픽이 많지 않고, 빠른 응답을 제공할 수 있는 경우, 비연결성의 특징은 효율적으로 작동한다.
하지만 비연결성도 한계를 가진다.
웹 브라우저로 사이트를 요청하면 HTML뿐만 아니라 자바스크립트, css, 추가 이미지 등 수많은 자원이 함께 다운로드 된다.
해당 자원들을 각각 보낼 때마다 연결 끊고 다시 연결하고를 반복하는 것은 비효율적이기 때문에
지금은 HTTP 지속 연결(Persistent Connections)로 문제를 해결한다.
- HTTP 지속 연결에서는 연결이 이루어지고 난 뒤 각각의 자원들을 요청하고 모든 자원에 대한 응답이 돌아온 후에 연결을 종료한다.
(HTTP 초기에는 각각의 자원을 다운로드하기 위해 연결과 종료를 반복해야 했다.)
단순함 , 확장 가능
HTTP 메시지
이전에 작성된 포스팅을 참고하고 읽으면 도움이 된다.
HTTP 참고 포스팅
잠시 정리만 해보자
- HTTP 메시지는 헤더와 바디로 구분
- HTTP 바디에서는 데이터 메시지 본문(Message body)을 통해서 표현(Representation) 데이터를 전달
- 페이로드(Payload): 데이터를 실어 나르는 부분
- 표현은 요청이나 응답에서 전달할 실제 데이터
- 표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공.
- 데이터 유형(html, json), 데이터 길이, 압축 정보 등...
헤더 형식은 위에서 보았다.
헤더 형식 <field-name>:<field-value>
<field-name>
은 대소문자 구분이 없다.
미디어 타입, 문자 인코딩
- Text/html; charset=utf-8
- application/json
- Image/png
• Content-Encoding: 표현 데이터의 압축 방식
표현 데이터 인코딩
- 표현 데이터를 압축하기 위해 사용
- 데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
- 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
- gzip, deflate, identity 등..
• Content-Language: 표현 데이터의 자연 언어
- ko, en, en-US ...
• Content-Length: 표현 데이터의 길이
- 바이트 단위
- Transfer-Encoding은 전송 시 어떤 인코딩 방법을 사용할 것인가를 명시한다. chunked의 방식으로 사용하기에 은 양의 데이터를 분할하여 보내기 때문에 전체 데이터의 크기를 알 수 없기 때문에 표현 데이터의 길이를 명시해야 하는 Content-Length 헤더와 함께 사용할 수 없다.
- 현재는 Transfer-Encoding보다는 Content-Encoding을 사용
From: 유저 에이전트의 이메일 정보
일반적으로 잘 사용하지 않음
검색 엔진에서 주로 사용
요청에서 사용
Referer: 이전 웹 페이지 주소
현재 요청된 페이지의 이전 웹 페이지 주소
A → B로 이동하는 경우 B를 요청할 때 Referer: A를 포함해서 요청
Referer를 사용하면 유입경로 수집 가능
요청에서 사용
referer는 단어 referrer의 오탈자이지만 스펙으로 굳어짐
User-Agent: 유저 에이전트 애플리케이션 정보
클라이언트의 애플리케이션 정보(웹 브라우저 정보, 등등)
통계 정보
어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
요청에서 사용
e.g.
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/
537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
Host: 요청한 호스트 정보(도메인)
요청에서 사용
필수 헤더
하나의 서버가 여러 도메인을 처리해야 할 때 호스트 정보를 명시하기 위해 사용
하나의 IP 주소에 여러 도메인이 적용되어 있을 때 호스트 정보를 명시하기 위해 사용
- 만약 Host 정보가 없다면 IP 주소만으로 어떤 도메인으로 요청이 왔는지 확인하기 어렵다.
Origin: 서버로 POST 요청을 보낼 때, 요청을 시작한 주소를 나타냄
여기서 요청을 보낸 주소와 받는 주소가 다르면 CORS 에러가 발생한다.
응답 헤더의 Access-Control-Allow-Origin와 관련
Authorization: 인증 토큰(e.g. JWT)을 서버로 보낼 때 사용하는 헤더
“토큰의 종류(e.g. Basic) + 실제 토큰 문자”를 전송
- Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Server: 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
응답에서 사용
e.g.
Server: Apache/2.2.22 (Debian)
Server: nginx
Date: 메시지가 발생한 날짜와 시간
응답에서 사용
e.g.
Date: Tue, 15 Nov 1994 08:12:31 GMT
Location: 페이지 리디렉션
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 리다이렉트(자동 이동)
201(Created): Location 값은 요청에 의해 생성된 리소스 URI
3xx(Redirection): Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를 가리킴
Allow: 허용 가능한 HTTP 메서드
405(Method Not Allowed)에서 응답에 포함
e.g.
Allow: GET, HEAD, PUT
Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
503(Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
e.g.
Retry-After: Fri, 31 Dec 2020 23:59:59 GMT(날짜 표기)
Retry-After: 120(초 단위 표기)
협상 헤더는 요청 시에만 사용한다
• Accept: 클라이언트가 선호하는 미디어 타입 전달
• Accept-Charset: 클라이언트가 선호하는 문자 인코딩
• Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
• Accept-Language: 클라이언트가 선호하는 자연 언어
- 클라이언트에서 Accept-Language로 KO를 작성해 요청한다면 서버에서는 해당 우선순위 언어를 지원할 수 있기 때문에 한국어로 된 응답을 돌려준다
서버에서 지원하는 언어가 여러 개일 때 클라이언트가 최우선으로 선호하는 언어가 지원되지 않는다면?
- 협상 헤더에서는 원하는 콘텐츠에 대한 우선순위를 지정할 수 있다.
1부터 0까지 우선순위를 부여하면 이를 토대로 서버는 응답을 지원한다.
• Quality Values(q) 값 사용
• 0~1, 클수록 높은 우선순위
• 생략하는 경우 1
- 1순위인 한국어를 서버에서는 지원하지 않지만 2순위인 영어를 지원하기에 서버에서는 우선순위에 있는 영어를 독일어보다 클라이언트가 선호하기에 영어로 응답을 주게 된다.
- HTTPS는 HTTP Secure의 약자로, 단어 뜻 그대로 기존의 HTTP 프로토콜을 더 안전하게(Secure) 사용할 수 있음을 의미한다.
- HTTPS는 HTTP와 달리 요청과 응답으로 오가는 내용을 암호화하기 때문에 더 안전하다.
HTTPS는 HTTP 통신을 하는 소켓 부분에서 SSL 혹은 TLS라는 프로토콜을 사용하여 서버 인증과 데이터 암호화를 진행한다.
- SSL이 표준화되며 바뀐 이름이 TLS이므로 사실상 같은 프로토콜이라고 생각하자.
과정
1. 서버는 클라이언트에게 요청을 받으면 CA에게 발급받은 인증서를 보내준다.
이 때, 사용자가 사용하는 브라우저는 CA들의 리스트와 공개 키를 내장하고 있다.
2. 우선 서버로부터 받은 인증서가 브라우저의 리스트에 있는 CA가 발급한 인증서인지 확인하고, 리스트에 있는 CA라면 해당하는 CA의 공개 키를 사용해서 인증서의 복호화를 시도한다.
3. CA의 비밀 키로 암호화된 데이터(인증서)는 CA의 공개 키로만 복호화가 가능하므로, 정말로 CA에서 발급한 인증서가 맞다면 복호화가 성공적으로 진행된다.
복호화가 성공적으로 진행 된다면, 클라이언트는 서버의 정보와 공개 키를 얻게 됨과 동시에 해당 서버가 신뢰할 수 있는 서버임을 알 수 있게 된다.
복호화가 실패한다면, 이는 서버가 보내준 인증서가 신뢰할 수 없는 인증서임을 확인하게 된다.
대칭 키 전달
이제 사용자는 서버의 인증서를 성공적으로 복호화하여 서버의 공개 키를 확보했다.위 과정에서 얻은 서버의 공개키는 클라이언트와 서버가 함께 사용하게 될 대칭 키를 주고 받을 때 쓰게 된다.
- 대칭 키는 속도는 빠르지만, 오고 가는 과정에서 탈취될 수 있다는 위험성이 있었다.
하지만 클라이언트가 서버로 대칭 키를 보낼 때 서버의 공개 키를 사용해서 암호화하여 보내준다면, 서버의 비밀 키를 가지고 있는게 아닌 이상 해당 대칭 키를 복호화할 수 없으므로 탈취될 위험성이 줄어든다.클라이언트는 데이터를 암호화하여 주고받을 때 사용할 대칭 키를 생성한다.
(대칭 키를 생성하는 데에는 더 복잡한 과정이 있지만, 일단은 대칭 키를 만든다는 것만 알아두자.)
클라이언트는 생성한 대칭 키를 서버의 공개 키로 암호화하여 전달한다.서버는 전달받은 데이터를 비밀 키로 복호화하여 대칭 키를 확보합니다. 이렇게 서버와 클라이언트는 동일한 대칭 키를 갖게된다.
이제 HTTPS 요청을 주고 받을 때 이 대칭 키를 사용하여 데이터를 암호화하여 전달하게 된다.
대칭 키 자체는 오고 가지 않기 때문에 키가 유출될 위험이 없어졌다.
따라서 요청이 중간에 탈취 되어도 제 3자가 암호화된 데이터를 복호화할 수 없게 됩니다.HTTPS는 이러한 암호화 과정을 통해 HTTP보다 안전하게 요청과 응답을 주고받을 수 있게 해준다.
서버와 클라이언트간의 CA를 통해 서버를 인증하는 과정과 데이터를 암호화하는 과정을 아우른 프로토콜을 SSL 또는 TLS이라고 말하고,
HTTP에 SSL/TLS 프로토콜을 더한 것을 HTTPS라고 한다.
위 내용을 가지고 암호화 방식을 이해했다고 할 수 없는거 같다.
이 내용은 추후에 조금 더 살펴보고 포스팅을 수정해야 겠다.