-
Notifications
You must be signed in to change notification settings - Fork 0
HTTP 1.1 → 2.0 → 3.0 개선하기
우리가 만든 서비스는 http/1.1을 사용하는걸 볼 수 있었다.
이에 대해 Lighthouse에서 2.0을 사용하라고 권장했다.
네트워킹의 흐름을 학습하며, 현대 웹의 요구사항에 부적합한 HTTP/1.1을 2.0과 3.0의 멀티플렉싱, 헤더 압축, 서버 푸시와 같은 최신 기능을 통해 속도, 보안, 효율성을 향상시키고, 이를 수치로 직접 비교해보기.
HTTP(HyperText Transfer Protocol)는 웹에서 데이터를 주고받는 서버-클라이언트 모델의 프로토콜.
쉽게 말하면 웹 브라우저가 서버와 통신하는 규칙
HTTP 통신 방법을 더 자세히 알아보자. 먼저 사용자가 웹사이트를 방문하면 브라우저가 웹서버로 리소스를 요청한다. 요청을 받은 웹서버는 HTML, CSS와 같은 리소스를 응답으로 돌려준다. 클라이언트의 요청과 서버의 응답 사이에는 여러 프락시 서버가 있다. 프락시 서버는 캐시를 보관하거나 보안을 위해 서버의 IP 주소를 숨기는 등 다양한 역할을 한다. 이 모든 통신은 안전하게 이뤄지기 위해 TCP(Transmission Control Protocol) 연결을 사용한다.
💡 TCP TCP는 데이터를 작은 조각(패킷)으로 나누어 전송하며, 각 패킷이 제대로 도착했는지 확인하고, 손실된 패킷은 다시 요청하여 재전송하는 과정을 거칩니다. 예를 들어, 사용자가 웹사이트를 로드할 때 HTML, CSS, 이미지 파일 등 모든 리소스를 정확하고 순서에 맞게 받아야 제대로 표시되는데, TCP가 이 과정을 책임집니다. 이를 통해 HTTP 통신이 끊김 없이 신뢰성 있게 작동할 수 있습니다.
브라우저, 서버가 주고받는 요청과 응답의 형태를 더 자세히 알아보자.
브라우저는 아래와 같은 HTTP 요청을 서버로 보낸다. 첫줄에는 HTTP 요청 메서드, URL 경로, HTTP 프로토콜 버전 정보가 있다. 두 번째 줄부터 모두 HTTP 요청의 헤더이다. key:value
쌍으로 이뤄져있다. 헤더는 웹사이트 도메인의 호스트, 사용자의 브라우저, 언어 등 서버가 필요한 정보를 전달한다.
GET /index.html HTTP/1.1
HOST: example.com
User-Agent: Mozilla/5.0
Accept-Langauage: ko-KR
요청에 문제가 없다면 서버는 아래와 같은 응답을 돌려준다. 첫 줄에는 HTTP 프로토콜 버전 정보와 HTTP 상태코드가 있다. 둘째 줄부터 보이는 key:value
쌍은 모두 헤더이다. 응답의 헤더는 브라우저가 필요한 정보를 전달해준다. 마지막으로 응답의 Body는 브라우저가 요청한 데이터이다. 아래 예시에서는 HTML 데이터를 돌려주고 있다.
HTTP/1.1 200 OK
Date: Sat, 07 Oct 2025 15:59:06 GMT
Server: Apache
Content-Type: text/html
<html>
...
</html>
클라이언트가 서버에 어떤 작업(조회, 생성, 수정, 삭제 등)을 요청할지 지정하는 방식.
-
GET
: 서버로부터 리소스를 요청하여 데이터를 조회합니다. (읽기 전용) -
POST
: 서버에 데이터를 전송하여 새로운 리소스를 생성합니다. -
PUT
: 서버의 리소스를 완전히 대체(갱신)합니다. -
DELETE
: 서버의 특정 리소스를 삭제합니다. -
PATCH
: 서버의 리소스의 일부를 수정합니다. (부분 갱신)
다른 요청 메소드로 HEAD
OPTIONS
TRACE
CONNECT
도 있지만, 위 5개가 CRUD 작업에 직관적으로 연결되고 REST API 표준에도 적합한 등의 이유로 주로 쓰인다.
HTTP 통신에서 브라우저와 서버는 데이터를 일반 텍스트로 교환한다. HTTP는 데이터를 암호화하지 않고 전송하기 때문에 제3자가 데이터를 가로채고 읽을 수 있다. 보안을 강화하기 위해 HTTP는 HTTPS(Hyper Transfer Protocol Secure)로 확장됐다.
HTTPS는 이름에서도 알 수 있듯이 HTTP의 더 안전한 버전이다. HTTPS에서는 브라우저와 서버가 데이터를 전송하기 전에 안젆하고 암호화된 연결을 생성한다. HTTPS는 모든 요청 및 응답을 SSL(Secure Socket Layer) 및 TLS(Transport Layer Security) 프로토콜에 따라 암호화한다. 그래서 HTTPS를 사용하면 카드 정보나 비밀번호와 같은 민감한 정보를 보호할 수 있다.
💡 SSL vs TLS SSL은 HTTPS의 초기 암호화 표준으로 사용되었지만, 현재는 보안이 강화된 TLS가 주로 사용됩니다. TLS는 클라이언트와 서버 간에 암호화 키를 교환하는 핸드셰이크 과정을 통해 안전한 연결을 설정하고, 전송 중인 데이터를 보호합니다. 예를 들어, HTTPS로 웹사이트에 접속하면 TLS가 신용카드 번호나 로그인 정보가 중간에 가로채여도 읽을 수 없도록 암호화합니다.
-
HTTP/0.9
- GET 메서드만 지원.
- HTML 파일만 읽을 수 있을 뿐, 클라이언트의 정보를 서버에 전달할 방법 X
- HTML 파일 중에서도 텍스트만 읽을 수 있다.
- HTTP 헤더 X, 상태 코드 X
-
HTTP/1.0
- POST 메서드 추가
- 덕분에 클라이언트의 정보를 전달할 수 있게 됨.
- HTML 뿐만 아니라 이미지나 동영상 등 다양한 정보를 주고받을 수 있게 됨.
- HTTP 헤더 O, 상태 코드 O
- 비연결성으로 인한 단기커넥션 → connection 하나당 1 Request & 1 Response 처리. 서버에 자원을 요청할 때마다 매번 새로운 연결을 해야했다.
- HTTP의 첫 번째 공식 표준 버전 (현재 가장 많이 쓰임)
- GET, POST 외에도 PUT과 DELETE가 생김.
- 또한, 하나의 TCP 연결을 재사용해 많은 콘텐츠를 전달할 수 있다.
지속 연결 (Persistent connection)
- 한 번 맺어졌던 연결을 끊지 않고 지속적으로 유지하여 불필요한 Handshake를 줄여 성능개선.
- 지정한 timeout 동안 연속적인 요청 사이에 커넥션을 닫지 않는다. 기존 연결에 대해서 handshake 생략 가능
파이프 라이닝 (pipelining)
- 여러개 요청을 보낼 때 처음 요청이 응답될 때까지 기다리지 않고, 요청을 한꺼번에 보내는 것.
- HTTP/1.1에서 기술적으로는 가능하지만, 대부분 브라우저들이 기본적으로 사용 X (HOLB문제도 있었고, 나중에는 2.0 버전으로 필요성이 없어짐)
💡HOLB (Head Of Line Blocking) 우선순위 원칙에 따라 첫번째 데이터의 응답 속도가 늦어지면 후순위에 있는 데이터 응답 속도도 같이 늦어지는 것.
- HTTP/1.1에서는 한 TCP 커넥션을 통해 요청을 보냈을 때, 응답이 오고 난 후에 같은 TCP 커넥션으로 다시 요청을 보낼 수 있었다 (위 사진처럼). 그래서 웹 브라우저들은 지연을 줄일려고 여러개의 TCP 커넥션을 만들어 동시에 여러개의 요청을 보내는 방법을 사용을 했었는데, TCP 커넥션을 무한정 만들수는 없기 때문에 한계가 있었음.
- HTTP 2에서는 하나의 TCP 커넥션에 여러 개의 스트림이 동시에 요청/응답 한다. Stream을 통해 요청과 응답이 묶일 수 있어 다수 개의 요청을 병렬적으로 처리 가능해졌다. 응답 프레임들은 요청 순서에 관계없이 완료된 순서대로 클라이언트에 전달 가능하다.
- 커넥션 낭비도 없고 병렬로 자원을 전송받아서 빨라짐.
2.0에서 개선된 점
- Binary Framing Layer
- 1.1 에서는 HTTP 메세지가 text로 전송되었지만, 본문은 압축이 되지만 헤더는 압축이 되지 않으며 헤더 중복값이 있다는 문제로 2.0에서는 binary frame으로 인코딩되어 전송되게 바뀌었다.
- 멀티 플렉싱 (multiplexing)
- 하나의 커넥션에 여러 개의 스트림이 동시에 요청/응답 한다.
- 1.1 버전은 한번에 하나의 파일만 전송이 가능하다. 비록 파이프라이닝 기술이 있지만, 여러 파일을 전송할 때 선행하는 파일의 전송이 늦어지면 HOLB(Head Of Line Blocking)이 발생. 이 문제를 해결하기 위해 2.0에서는 여러 파일을 한번에 병렬로 전송.
- Server Push
- 2.0 에서는 클라이언트의 요청에 대해 미래에 필요할 것 같은 리소스를 똑똑하게 미리 보낼 수 있다.
- 예를 들어 클라이언트로부터 HTML 문서를 요청하는 하나의 HTTP 메세지를 받은 서버는 그 HTML 문서가 링크하여 사용하고 있는 이미지, CSS 파일, JS 파일 등의 리소스를 스스로 파악하여 클라이언트에게 미리 push해서 미리 브라우저의 캐시에 가져다 놓는다.
- Stream Prioritization
- 1.1 에서 파이프라이닝 이라는 혁신적인 기술이 있었지만, 우선 순위 문제 때문에 HOLB가 발생했다. 2.0 에서는 리소스간 의존관계(우선순위)를 설정하여 이런 문제를 해결하였다. (우선순위 지정 트리 사용)
- 병렬로 처리하긴 하지만, 자원은 제한되어 있으므로 중요한 요청부터 효율적으로 처리하기 위해 우선순위가 필요하다.
- HTTP Header Data Compression
- HTTP 1.1 에서 헤더는 아무런 압축 없이 그대로 전송되었다. 이를 개선하기 위해 HTTP 2.0에서는HTTP 메시지의 헤더를 압축하여 전송한다.
- 웹 응답속도가 1.1에 비해 15~50% 향상 된다고 한다.
- 대부분의 사이트들은 HTTP 2를 지원.
2.0의 문제점
-
여전한 RTT
- 개선이 되었긴 하지만, 여전히 TCP를 사용하기 때문에 Handshake의 RTT로 인한 지연 시간이 발생한다(근본적으로 TCP로 통신하는게 문제). TCP 연결 진행한 다음 보안에 대한 연결을 진행해서 최소 2회 이상의 RTT가 발생.
💡RTT (Round Trip Time) 클라이언트가 서버로 패킷을 보내고, 서버가 응답을 보내 다시 클라이언트에 도달하기까지 걸리는 왕복 시간.
-
TCP 자체의 HOLB
-
분명 HTTP 2에서 HTTP 1.1의 파이프라이닝 HOLB 문제를 멀티플렉싱을 통해 해결했다고 하였다.하지만 기본적으로 TCP는 패킷이 유실되거나 오류가 있을때 재전송하는데, 이 재전송 과정에서 패킷의 지연이 발생하면 결국 HOLB 문제가 발생된다. TCP/IP 4계층을 보면, 애플리케이션 계층(L4)에서 HTTP HOLB를 해결하였다 하더라도, 전송 계층(L3)에서의 TCP HOLB 를 해결한건 아니기 때문이다.
-
-
중개자 캡슐화 공격
- HTTP 2.0은 헤더 필드의 이름과 값을 바이너리로 인코딩한다. 이를 다르게 말하면 HTTP 2.0 이 헤더 필드로 어떤 문자열이든 사용할 수 있게 해준다는 뜻이다. 그래서 이를 악용하면 HTTP 2.0 메시지를 중간의 Proxy 서버가 HTTP 1.1 메시지로 변환할 때 메시지를 불법 위조할수 있다는 위험성이 있다. 다행히 거꾸로 HTTP/1.1 메시지를 HTTP/2.0 메시지로 번역하는 과정에서는 이런 문제가 발생하지 않는다.
-
길다란 커넥션 유지로 인한 개인정보 누출 우려
- HTTP 2.0은 기본적으로 성능을 위해 클라이언트와 서버 사이의 커넥션을 오래 유지하는 것을 염두에 두고 있다.하지만 이것은 개인 정보의 유출에 악용될 가능성이 있다. 이는 HTTP/1.1에서의 Keep-Alive도 가지고 있는 문제이기도 하다.
- TCP는 연결 진행한 다음 보안에 대한 연결을 진행해서 최소 2회 이상의 RTT가 발생하지만, QUIC는 1RTT만에 연결수립과 보안을 동시에 진행함.
💡QUIC (Quick UDP Internet Connections) 구글이 개발한 프로토콜로, TCP의 신뢰성과 UDP의 속도를 결합한 새로운 전송 프로토콜. (UDP를 기반으로 추가적인 기능을 구현)
3.0에서 개선된 점
-
잔존하던 HOLB 현상 해결
-
2.0은 스트림에서 여러가지 프레임들이 뒤 섞여 이동되는데, 만약 하나의 프레임에 문제가 생기면 상관없는 뒤 프레임까지 영향이 간다.
-
TCP를 QUIC로 대체해서 스트림 자체를 독립적으로 여러개 나누어서 처리(독립 스트림). 독립적으로 다루므로 특정 스트림에서 HOLB가 발생하더라도, 다른 스트림에 영향 X
-
-
패킷 손실 감지에 걸리는 시간 단축
- 패킷 손실이 발생했을 때 이를 빠르게 감지하고 재전송할 수 있도록 한다.
- 물론 독립 스트림으로 따로 다뤄서 패킷 손실이 다른 스트림에 영향을 주지는 않지만, 해당 스트림의 복구를 빠르게 해주는 역할을 한다.
-
향상된 멀티플렉싱
-
보안 강화
- QUIC 내에 TLS가 포함되어 있기 때문에 TCP와 달리 헤더 영역도 암호화된다.
UDP는 신뢰성이 낮다???
TCP와 UDP를 비교했을때, UDP는 기능이 거의 없어서 빠르지만 신뢰성이 낮으므로, 조금 느리더라도 신뢰성이 높은 TCP를 사용했다고 예전에 들어봤을 것이다.
하지만, UDP는 신뢰성이 없는게 아니라 탑재를 안한 것이다. 커스터마이징을 통해 신뢰성도 확보 가능하다.
- 기존 체계 호환성 문제.
- QUIC는 패킷별로 암호화를 하므로 리소스가 많이 듬.
- QUIC는 CPU를 많이 사용함.
- 대부분 HTTP/2.0을 사용한다.
- BUT, 검색할 때 HTTP/3.0을 사용하는 것을 확인할 수 있다.
- 대부분 HTTP/3.0을 사용한다.
chrome-extension
프로토콜
- Chromium 기반 브라우저(예: Chrome, Edge)에서 브라우저 확장 프로그램이 사용하는 프로토콜. 특정 확장 프로그램이 설치되어 있을 때만 발생.
- Edge 브라우저에서만 뜨고 Chrome에서는 해당 프로토콜 요청이 안뜬다.
- Edge에 설치된 Google Tag Assistant 확장 프로그램 때문에 발생한 것이다. 확장 프로그램의 설치와 동작 여부를 확인하는 요청 리소스이다.
- Chrome에는 Tag Assistant가 설치되지 않았기 때문에 발생하지 않는다.
- Edge Inprivate 모드에서도 안뜬다.
- 엣지는 기본적으로 InPrivate 모드에서 확장 프로그램을 비활성화한다.
data
프로토콜
-
인라인 데이터를 URL로 인코딩하여 서버 요청 없이 브라우저에서 직접 처리합니다.
-
인라인 데이터는 데이터를 외부 파일로 저장하거나 서버 요청을 통해 가져오는 대신 HTML, CSS 또는 JS 코드 내에 직접 포함하여 사용하는 데이터.
-
인코딩은 데이터를 특정 형식으로 변환하여 컴퓨터가 이해하거나 전송할 수 있도록 만드는 작업. URL로 인코딩 한다는 것은 데이터를 URL 형식에 맞게 변환하는 것.
-
주로 작은 리소스(이미지, 텍스트 등)를 외부 파일 없이 포함할 때 사용되며, Base64로 인코딩된 데이터를 활용합니다.
프로토콜 처리 속도 data
프로토콜서버 요청 없음 → 즉시 처리. 평균 1~2ms 이하. HTTP 요청 DNS 조회 + 서버 요청/응답(대기 시간 포함) → 50~300ms 이상. -
예시: 이미지 데이터를 Base 64로 인코딩
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAU...">
방식 1: 컨테이너 내부 직접 수정 방식
- Powershell에서 다음 순서대로 작업을 진행:
-
ssh [email protected]
로 원격 서버에 접속 -
비밀번호 입력 후, 컨테이너 내부 쉘로 진입
sudo docker exec -it refactor-web31-boolock-frontend-1 /bin/sh
-
컨테이너 내부의 Nginx 설정 파일 열기
vi /etc/nginx/conf.d/default.conf
-
HTTP/2.0 적용을 위한 설정 코드 추가.
-
- 문제점
- 이 방식은 컨테이너 내부의 설정 파일만 변경되므로, 컨테이너를 재배포하거나 새로 생성하면 변경 사항이 초기화됨.
- 팀원들이 동일한 컨테이너를 사용하지 않으면 설정이 반영되지 않을 가능성이 있음.
방식 2:
수정 전 nginx.conf
(HTTP/1.1)
server {
listen 80;
server_name boolock.site;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name boolock.site;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application;
gzip_min_length 256;
}
수정 후 nginx.conf
(HTTP/2.0)
server {
listen 80;
server_name boolock.site;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
server_name boolock.site;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application;
gzip_min_length 256;
}
-
http on;
이 한 줄만 추가됐다. - Nginx 설정이 올바른지 테스트 후 재시작
- 테스트 → nginx -t
- 재시작 → nginx -s reload
Before
**After (**유의미한 변화는 없다.)
참고
- 로컬 개발 환경에서는 HTTPS 인증서를 설정하지 않으므로
http://
로 동작 - HTTP/2는 기본적으로 HTTPS 환경에서만 동작한다. 따라서 로컬에서는 HTTP/1.1로 동작.
Q. “저는 계속 HTTP/1.1 프로토콜이 떠요 ㅠㅠ”
→ 캐시를 지우고 다시 해보세용.
수정 전 nginx.conf
(HTTP/2.0)
server {
listen 80;
server_name boolock.site;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
server_name boolock.site;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application gzip_min_length 256;
}
수정 후 nginx.conf
(HTTP/3.0)
server {
listen 80;
server_name boolock.site;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
http3 on;
quic_retry off;
server_name boolock.site;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
add_header Alt-Svc 'h3-23=":443"; ma=86400';
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application;
gzip_min_length 256;
}
- http3 on; → HTTP/3.0 프로토콜을 활성화하는 설정
- quic_retry off; → QUIC 연결에서 재시도를 비활성화하는 설정 (QUIC는 초기 핸드셰이크 중 연결 설정을 재시도 할 수 있어서 불필요한 재시도 시간 절약)
- ssl_protocols TLSv1.3; → 서버에서 지원하는 SSL/TLS 프로토콜을 TLS 1.3으로 제한. (TLS 1.3이 1.1, 1.2 버전보다 보안과 성능이 좋다)
- ssl_prefer_server_ciphers off; → 서버가 아니라 클라이언트가 원하는 암호화 방식을 우선적으로 사용하도록 설정.
- add_header Alt-Svc 'h3-23=":443"; ma=86400'; → HTTP 헤더에 Alt-Svc를 추가하여 브라우저가 HTTP/3.0을 사용할 수 있도록 알린다. (ma=86400은 Alt-Svc 정보를 캐시에 저장하는 유효 기간으로 86400초 = 1일 이다)
- h2 요청과 h3 요청이 섞여있다.
- 근데 헤더를 보면 h3로 잘 온다.
h3 연결했는데 왜 일부는 h2로 뜰까?
- 기존 연결의 재사용
- 브라우저는 기존 연결을 재활용하려는 경향이 있다. Alt-Svc를 통해 HTTP/3가 지원된다는 정보를 받아도, 이미 열린 HTTP/2 연결이 있다면 이를 계속 사용할 수 있다.
- 브라우저 정책
- 브라우저는 HTTP/3가 상대적으로 새로운 프로토콜이기 때문에 초기 요청에는 HTTP/2로 연결을 시도하며 안정성을 유지하려고 한다.
성능 개선은 미미했지만, 네트워킹 흐름을 공부도 하고 최신 웹 표준 프로토콜로 보안 확보했잖아 한잔해~
🌐 참고 링크