HTTP Protocol

Violet_Evgadn·2023년 4월 26일
0

네트워크

목록 보기
4/37

HTTP Protocol

HTTP Protocol란?

브라우저는 이전 단계에서 설명했던 대로 URL을 해독하여 어떤 서버에 어떤 동작을 위해 액세스 하는지 판명했다.

이후 브라우저는 HTTP Protocol을 활용해 웹 서버에 액세스 하게 된다.

Protocol을 직역하면 "규약"이라고 말할 수 있다.

그리고 이전에 말했듯 HTTP는 웹 서버에게서 웹 문서 및 데이터를 받아올 수 있는 Protocol이다.

이 둘을 합치면 웹 서버에서 웹 문서 및 데이터를 받아오는 방법 전체에 대한 규약임을 알 수 있으며 쉽게 말하자면 Request와 Respond를 주고받는 방법(데이터 및 순서)을 정한 것이라 이해할 수 있다.

HTTP Protool의 기본 개념은 단순하다.

먼저 Client가 서버를 향해 Request Message를 보낸다.

Request Message에는 "무엇을" "어떤 방식으로" 웹 서버에서 받아오거나 웹 서버 로직을 실행시킬지 적혀 있다.

"무엇"에 해당하는 것은 URI로써 보통 불러 오고 싶은 페이지의 파일 이름이나 CGI 프로그램 파일명을 사용한다.

그리고 어떤 데이터를 결정했다면 이 데이터를 어떤 방식으로 받아올지 결정해야 하는데 이를 "HTTP Method"라고 한다.

URI와 HTTP Method 및 추가 정보를 통해 만들어진 Request Message가 웹 서버에 도착하면 서버는 메서드 및 URI를 파악하고 요청한 동작을 수행한다.

그리고 동작을 통해 만들어진 결과물을 응답 메시지(Respond Message)에 저장한다.

이 때 응답 메시지 맨 앞에는 웹 서버에서 동작을 정상적으로 실행했는지를 나타내는 값인 Status Code를 적재한다.

이렇게 만들어진 Respond Message가 Clinet 측에 도착하여 브라우저가 Respond Message에서 Status Code와 데이터를 추출하여 화면에 표시함으로써 HTTP Protocol 전 과정이 끝나는 것이다.

CGI 프로그램이란?

URI를 설명할 때 불러오고 싶은 페이지의 파일이나 CGI 프로그램 파일을 사용한다고 적었다.

불러오고 싶은 페이지는 정적 HTML 파일일 것인데 CGI 프로그램은 무엇일까?

CGI란 공통 게이트웨이 인터페이스(Common Gateway Interface)의 약어로써 웹서버와 외부 프로그램 사이에서 정보를 주고받는 방법이나 규약을 말한다.

웹 서버 SW에서 프로그램을 호출할 때 규칙을 정한 것이 CGI이며 CGI 규칙에 맞게 움직이는 프로그램을 CGI 프로그램이라고 한다. 조금 더 풀어 설명해 보자.

웹 서버의 종류는 여러 가지일 것이고 웹 서버 내부에 있는 프로그램이 많을 수도 있을 것이다.

이런 경우 웹 서버는 어떻게 그리고 어떤 프로그램에게 입출력을 주고받을지 알고 있어야 한다.

이러한 누구에게 어떻게 정보를 주고받을지 결정한 규약을 CGI라고 하며 CGI 표준에 맞춰 만들어진 스크립트를 CGI 스크립트라고 한다.

그리고 이런 CGI 표준에 맞춰 프로그램을 만들면 CGI 프로그램이 되는 것이다.

출처 : https://electricalfundablog.com/common-gateway-interface-cgi/

브라우저에서 HTTP Request를 웹 서버 측에 보낸다.

만약 URI에 CGI 프로그램이 적혀있다면 웹 서버는 CGI Gateway를 통해 로직을 수행할 CGI Program에게 Request를 전달한다.

CGI Program은 Reqeust에 맞는 동작을 수행하여 DB에 Query를 보내던가 내부 로직을 수행할 것이다. 이렇게 만들어진 결과물을 Server에 보내고 서버는 HTTP Response를 브라우저에게 보냄으로써 사용자는 동적인 웹 서버를 사용할 수 있게 된다.


REST

REST란?

HTTP Protocl은 URI와 HTTP Method를 통해 웹 서버에게 Request를 수행한다고 말했다.

URI와 HTTP Method를 공부하기 전 꼭 알아야 하는 개념이 있는데 바로 REST이다.

REST는 Representational State Transfer의 약자로써 2000년도 로이 필딩의 박사학위 논문에서 최초 소개된 개념이다.

로이 필딩은 그 당시 웹 설계(HTTP) 우수성에 비해 제대로 활용되지 못한다고 생각하여 웹의 장범을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다.

REST는 총 3가지 구성으로 되어 있다.

  • 자원(Resource) : URI
  • 행위(Verb) : HTTP Method
  • 표현(Representations) : 서버가 응답할 때 데이터를 담는 형식(JSON, XML 등)

REST 특징

일관된 인터페이스(Uniform Interface)

HTTP를 사용할 수 있는 환경이라면 플랫폼과 Resource Type 등에 관계없이 항상 한정적인 인터페이스로 Requst 및 Respond를 처리한다.

무상태성(Stateless)

각각의 요청에 대한 정보를 저장하지 않고 별개 요청으로 처리한다.

이후에 배우겠지만 페이지를 만들 때 이미지 파일이나 영상 파일이 있을 경우 태그라는 것을 활용해 태그에 대한 Request를 다시 보내게 된다.

이때 웹 서버 측에서 이전에 만들어진 HTML 파일을 기억하고 있다가 태그에 대한 새로운 Request가 오면 비어 있는 공간에 영상 파일을 추가하여 완성된 HTML 파일을 보내지 않는다.

웹 서버는 그냥 HTML 파일 중 텍스트 부분을 먼저 처리한 뒤 클라이언트에게 보내고 다시 태그에 대한 Request가 올 경우 태그에 대한 Respond값만 보내준다.

REST의 경우 세션이나 쿠키 정보를 웹 서버에서 별도로 저장 및 관리하지 않고 단순히 들어오는 요청만 처리하면 되므로 서비스 자유도가 높아지며 구현이 쉬워지고 서버 부담 또한 줄일 수 있다.

캐시가능(Cacheable)

REST는 HTTP 웹 표준을 그대로 활용하고 있으므로 HTTP가 가진 캐싱 기능 또한 사용 가능하다.

캐시 기능을 통해 같은 URI에 대한 반복된 요청을 효율적으로 처리할 수 있다.

자체 표현 구조(Self-descriptiveness)

REST는 구조가 명확하고 쉽게 되어 있기 때문에 REST 메시지만 봐도 무엇을 어떻게 수행하고 싶어 하는지 직관적으로 이해할 수 있다.

Client - Server 구조

REST 환경은 Server는 API를 제공하며 Client 측은 사용자 인증이나 컨텍스트(세션, 쿠키, 로그인 정보 등)를 전담하는 구조를 가지고 있다.

이렇게 서로의 역할이 명확히 구분되어 있으므로 각자가 수행할 내용이 명확해지며 서로에 대한 의존성이 줄어들게 된다.

계층형 구조

REST 환경에서 Server는 다중 계층으로 구성될 수 있고 클라이언트는 이러한 계층에 대해 인지할 필요가 없고 할 수도 없다.

따라서 서버 측에서 보안, 로드 밸런싱, 암호화를 위한 계층을 추가하여 구조상 유연성을 둘 수 있으며 Proxy, 게이트웨이 같은 네트워크 기반 중간매체를 사용할 수도 있다.

RESTful API(REST API)

REST API는 ~ful 접미사의 의미만 알면 바로 이해 가능한데 ~ful이란 단어에 "가득 찬"이란 의미를 추가해 준다.

즉 REST API(RESTful API)란 REST 개념을 충분히 지키는(REST 개념으로 가득 차 있는) API를 의미한다.

REST API를 위한 디자인 가이드가 몇 개 존재하는데 가장 중요한 항목은 2가지이다.

  • URI는 정보의 자원을 표현해야 한다.
  • 자원에 대한 행위를 HTTP Method로 표현한다.

이를 간단히 말하면 URI와 HTTP Method만 보고서도 API가 어떤 데이터를 얻어오고 싶은지, 혹은 웹 서버에서 어떤 행위를 수행하고 싶은지를 알 수 있어야 한다는 것이다.

이런 규칙을 지키기 위해 REST API를 위한 몇 가지 추천 사항들이 존재한다.

먼저 URI는 동사보다는 명사를 많이 활용해야 한다.

URI는 정보의 자원만을 표시해야 하며 동작은 HTTP Method를 통해 알 수 있어야 한다.

"자원"은 명사로 표현 가능하며 동사는 주로 행위(동작)를 위한 단어이다. 이 때문에 URI에는 명사를 사용하는 것을 추천한다.

두 번째로 URI 마지막 문자로 슬래시 구분자(/)를 사용하지 않는 것을 추천한다.

URI 설계를 수행할 때 슬래시 구분자(/)는 계층 관계를 나타내기 위해 사용된다.

예를 들어 SSG Landers 13번 선수의 정보를 알기 위하여 "/ssg/landers/player/13"으로 URL을 설정하는 것이다.

REST API는 URI를 통해서만 리소스를 파악하는데 마지막 슬래시가 붙어 있을 경우 리소스 파악에 악영향을 끼칠 수 있다.

세 번째로 가독성을 높이기 위하여 밑줄(_)보다는 하이폰(-) 사용을 추천한다.

"www.sample_site.com"처럼 밑줄이 있는 경우 URL 가독성이 떨어진다. 따라서 하이폰 사용이 추천된다.

마지막으로 URI로 소문자만 사용하는 것이다.

도메인 부분은 대소문자를 구분하지 않는다. 하지만 경로 부분은 서버 환경에 따라 대소문자를 구분할 수도 있고 아닐 수도 있다.(ex : Window는 대소문자를 구분하지 않지만 Linux는 구분함)

이 때문에 소문자로 통일하여 안전하고 사용성을 증가시키는 게 추천된다.

URI VS URL

REST의 구성 요소 중 URI에 대해 먼저 공부해 보자.

네트워크를 공부하다 보면 헷갈리는 개념 중에 하나가 URL과 URI이다. 심지어 URL 값을 URI 값으로도 활용할 수 있기 때문에 더욱 복잡해진다.

URI와 URL을 구별하는 개념은 아래와 같다.

URI는 식별자로(Identifier)로써 다른 항목과 구분하기 위해 필요한 정보이다.
URL은 접근하고자 하는 리소스에 어떻게 도달하는지까지 명시하는 정보이다.

출처 : https://velog.io/@rlaclghks123/Today-I-Learn-URI%EB%9E%80

URI는 어떤 브라우저나 어떤 환경에서 접근하더라도 늘 동일한 Resource(HTML 텍스트, 이미지, 비디오 등)을 보여줄 수 있게 하는 고유 식별자이다.

URL은 네트워크 상 Resource가 위치한 정보를 나타내주는 문자열이다.

그리고 URN이라는 것도 존재한다.

URN은 Uniform Resouce Name의 약자로써 Resource의 위치를 신경 쓰지 않고 이름만을 사용하여 Resource에 접근하기 위한 값으로써 리소스를 영구적이고 유일하게 식별할 수 있는 값이다.

URN은 Resource 위치 정보를 취급하지 않으므로 프로토콜은 필요 없으며 대신 고유한 리소스 자원을 위한 추가 값이 필요한데 Query String(HTML Parameter)와 Fragment(Anchor)가 존재한다.

이를 통해 URI가 어떻게 모든 환경에서 동일한 Resource를 받을 수 있는지 유추해 볼 수 있다.

먼저 URN에 기입된 Name을 통해 실제 자원을 찾기 위하여 URL로 변환한다. 이후 Name에 해당하는 파일을 찾을 경우 URN에 기입된 Query String 및 Fragment를 활용하여 요청에 맞는 정적이고 고유한 HTML 파일을 만들 것이고 이렇게 만들어진 HTML 파일이 브라우저(Client)에게 전달될 것이다.

결국 동일한 URI를 사용할 경우 사용되는 Resource가 동일하며 정적인 HTML 파일을 만들기 위해 사용되는 데이터 또한 동일하므로 모든 환경에서 동일한 자원을 반환받을 수 있고, URI가 식별자로써의 역할을 할 수 있는 것이다.

현실로 예를 들어보자. 내가 현재 성균관대학교를 대중교통을 타고 가고 싶다고 가정하자.

URL은 성균관대학교의 주소(경기 수원시 장안구)를 의미하며 URN은 "성균관대학교"라는 이름을 의미한다.

먼저 지도 앱에 "성균관대학교"를 목적지로 지정할 것이다.

그렇다면 지도 앱은 성균관대학교가 있는 주소(URL)를 찾아 목적지를 "성균관대학교"가 아닌 성균관대학교 주소로 잡아줄 것이다.

이후 추가 데이터로 "대중교통으로 가겠다"라는 요구사항을 넣어준다.(Query String or Fragment)

그렇다면 성균관대학교로 갈 수 있는 많은 방법 중 대중교통으로 가는 방법만 띄워줄 것이다.

이런 과정은 모든 지도앱에서 동일하므로 현재 위치가 동일할 경우 어떤 지도앱을 사용하더라도 동일한 결과를 반환할 것이다.

출처 : https://danielmiessler.com/study/difference-between-uri-url/

설명한 내용을 정리하면 위 사진과 같은 밴 다이어그램이 그려진다. 그리고 매우 중요한 사실을 알 수 있다.

"URL은 URI이지만, 모든 URI는 URL이 아니다"

HTTP Method

REST의 구성 요소 중 HTTP Method에 대해 알아보자.

HTTP Method는 HTTP Protocol을 통해 어떤 작업을 하고 싶은지 전달해 주는 데이터이다.

"index.html" 파일에 요청을 보낼 때 단순히 index.html 파일을 얻어오고 싶을 수도 있고 index.html 파일에 기입한 데이터를 DB에 저장시키고 싶을 수도 있는데 이런 동작을 HTTP Method를 통해 구분할 수 있다.

HTTP Method의 개념은 간단하기 때문에 설명은 이 정도로 마치고 HTTP Method의 종류에 대해 알아보자.

  • ★ GET : Resource 조회
  • ★ POST : 서버로 (사용자가 입력한) 데이터를 송신. 주로 데이터를 DB에 등록하기 위해 사용
  • PUT : Resource를 덮어쓰기 위해 주로 사용됨. 만약 해당 리소스가 없을 경우 생성
  • DELETE : Resource 삭제
  • PATCH : Resource 변경.
    • PUT은 Resource 전체를 변경하지만 PATCH는 Resource 일부만 변경시킴
  • HEAD : GET과 동일하지만 Body 부분을 제외하고 HTTP Message Header만 반환
    • 주로 파일의 최종 갱신 일시 등 Resource Meta Data를 취득하기 위해 사용함
  • OPTIONS : Resource에 대한 통신 가능 Option(HTTP Method)을 설명
    • Resource에 접근하기 위해 사용할 수 있는 HTTP Method 정보들을 받기 위해 사용함
  • TRACE : 서버 측에서 받은 리퀘스트 Line과 Header를 그대로 Client로 반송
    • Proxy 서버 등을 사용하는 환경에서 Request가 치환되는지와 어떻게 치환되는지를 파악하기 위해 사용
  • CONNECT : Resource에 대한 경로를 따라 메시지 루프백 테스트를 수행
    • 암호화한 메시지를 Proxy로 전송할 때 이용하는 메서드

주요 메서드는 굵은 글씨로 되어 있는 GET, POST, PUT, PATCH, DELETE이며 그중에서도 GET과 POST는 꼭 알아야 한다.

HTTP Ver 1.0에서는 GET과 POST만 사용되었고 PUT과 DELETE는 부가 기능정도로만 부록에 소개되었다.

HTTP Ver 1.1에서는 위에 나온 모든 HTTP Method를 사용할 수 있다고 설명되어 있다.

그렇다면 HTTP Method 중 가장 중요한 GET과 POST에 대해 자세히 알아보자.

GET

GET은 웹 서버에 액세스 하여 리소스를 조회하기 위해 사용하는 메서드이다.

CRUD(Create, Read, Update, Delete)에서 Read 작업을 수행하는 HTTP Method라고 할 수 있다.

GET을 통해 웹 서버에 데이터를 전달하고 싶다면 Query String을 활용한다.

Query String은 URL을 설명하며 같이 설명했으므로 자세한 설명은 하지 않겠다.

Query String을 사용하지 않고 Request Message Body에 데이터를 넣고 서버에 전달할 수도 있긴 하지만 서버 측에서 이러한 메시지에 대한 처리 과정을 따로 구성해야 하므로 권장하지 않는다.

POST

웹 서버 측에 데이터를 전달한 뒤 처리를 요청할 때 많이 활용되는 HTTP Method이다.

웹 서버는 프로그램 내부 로직이나 DB에 데이터를 저장함으로써 데이터를 처리하게 된다.

POST는 주로 새로운 데이터를 DB에 넣거나 새로운 자원을 만들기 위해 활용되므로 CRUD 작업 중 Create 작업을 수행하는 HTTP Method라고 할 수 있다.

POST는 Request Message Body에 (주로 사용자가 입력한) 데이터를 저장하여 서버에 전달하고 서버는 이를 활용해 데이터를 처리한다.

폼(Form)에 사용자가 입력값을 입력하고 웹 서버에 송신하는 경우 많이 사용하는 HTTP Method이다.

기본적으로 POST 메서드를 사용할 때는 URI에 웹 서버에서 동작시키고 싶은 Application 프로그램 파일 명(ex : index.cgi, index.php)을 입력한다.

하지만 이후 자세히 배우겠으나 최근에는 Apache Tomcat 등의 Servlet Container를 통해 데이터를 처리하므로 GET과 마찬가지로 URI가 입력된다.

추가로 POST를 통해서도 웹 서버의 리소스를 조회할 수 있으나 GET 메서드는 캐싱이 가능한 반면 POST 메서드는 캐싱이 되지 않으므로 리소스 조회를 위해서라면 GET을 사용하는 것이 유리하다.

멱등성(Idempotence)

HTTP Method를 공부하다 보면 가끔 멱등성이라는 용어가 나올 때가 있다.

멱등성이란 여러 번 수행해도 결과가 같음을 의미한다.

즉, 멱등성을 가지고 있는 로직은 몇 번을 수행하든 1번 수행한 것과 동일한 결과를 내는 것이다.

(올바르게 구현했을 경우) GET 메서드는 멱등성을 가지며 POST 메서드는 멱등성을 가지지 않는다.

예시를 들면 잘 알 수 있다. 예를 들어 "https://www.naver.com"을 1개 브라우저에서 10번 입력해 보자.

그렇다고 똑같은 창이 10개 생성된다거나 숨겨진 이벤트가 발생한다거나 하는 상황은 벌어지지 않는다. 단지 네이버의 홈 페이지가 나올 뿐이다.

즉, 1번 실행한 것과 10번 실행한 것이 동일한 결과를 내므로 멱등성을 가지는 것이다.

이제는 POST를 통해 회원가입을 하는 경우를 생각해 보자.

회원가입을 수행한 뒤 똑같은 ID로 회원가입을 수행해 보자. 이 경우 "동일한 ID를 가진 회원이 존재합니다" 등의 문구를 띄우며 회원가입이 수행되지 않을 것이다.

즉, 1번 실행한 것과 2번 실행한 것이 동일한 결과를 내지 않으므로 멱등성을 가지지 않는 것이다.

PUT과 DELETE는 위험할까?

공부를 하다 특정 문구를 읽으며 의문점이 생겼다.

보안상 문제가 있거나 GET과 POST 이외의 메서드를 사용하는 클라이언트가 널리 보급되어 있지 않다는 이유로 이러한 사용법(PUT, DELETE 등을 사용하는 것)을 쓰진 않지만, ~

이를 읽다 보니 PUT과 DELETE가 보안상 위험한 것인지, 만약 그렇다면 왜 위험한지가 궁금해졌다.

사실 "PUT"과 "DELETE"만 놔두고 보자면 보안 상 문제가 존재하지 않는다.

문제는 서버 관리자가 "PUT"과 "DELETE"의 존재를 모를 수 있다는 것이다.

이 경우 자주 사용되는 GET과 POST에 대해선 서버 측에서 보안 설정이 되어 있으므로 안전하지만 PUT과 DELETE에 대한 보안 설정은 누락되어 있기 때문에 심각한 보안적 취약점이 발생할 수 있다.

또한 필자는 보안 쪽에 대해 공부를 깊게 하지 않아서 잘 모르겠지만 PUT과 DELETE는 GET과 POST와는 다른 방식으로 보안 관리를 수행해야 할 수도 있으며 이 경우 서버 측 보안 설정이 더욱 복잡해지게 될 것이다.

이런 문제를 피하기 위하여 개발자와 서버 관리자가 협업을 하며 업무를 진행할 수도 있을 것이다.

하지만 서버 관리자와 개발자 모두 협의를 통해 업무를 진행하는 것보다는 서버 관리자는 단순히 GET과 POST만 보안 설정을 해 둔 뒤 나머지 HTTP Method는 사용을 막아두고 개발자는 GET과 POST만 사용하여 개발을 진행하는 것이 더욱 간편한 해결방법이다.

그리고 HTTP의 모든 Method가 활성화되었을 때는 WebDAV Extension이라는 것이 활성화되는데 이 과정에서 보안적 문제가 발생할 수도 있다.

이러한 이유 때문에 책에서 위와 같은 문구가 나오지 않았나 싶다.

그리고 개인적인 생각이지만 HTTP 1.0 버전에는 GET과 POST만 사용으로 정의되어 있고 PUT과 DELETE는 부가 기능으로 기술되어 있는 것도 한몫하지 않았을까 싶다.

현재 네이버 사이트에서도 PUT과 DELETE를 사용하고 있으니 메서드 자체엔 잘못이 없다는 것을 알아두자.

(항상 문제는 사용하는 사람...)

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글