PromleeBlog
sitemap
aboutMe

posting thumbnail
HTTP와 HTTPS 웹의 언어 - 코딩과 함께 배우는 네트워크 6일차
HTTP and HTTPS The Language of the Web - Learning Network with Coding Day 6

📅

🚀

들어가기 전에 🔗

지난 시간에는 데이터를 안전하게 또는 빠르게 전달하는 TCP와 UDP 프로토콜에 대해 알아보았습니다.
오늘은 우리가 매일같이 사용하는 월드 와이드 웹(World Wide Web)을 가능하게 하는 핵심 언어, 바로
HTTP 프로토콜
과 그의 안전한 형제인
HTTPS 프로토콜
에 대해 깊이 탐구해 보겠습니다.

🚀

HTTP (HyperText Transfer Protocol) 🔗

HTTP는 'HyperText Transfer Protocol'의 줄임말로, 웹 서버와 웹 클라이언트(주로 웹 브라우저) 사이에서 HTML 문서나 이미지, 동영상 같은
하이퍼텍스트
문서를 주고받기 위한 약속(프로토콜)입니다.
쉽게 말해, 웹 브라우저가 웹 서버에게 "이 웹 페이지 좀 보여줘!" 하고 요청하면, 웹 서버가 "알겠어, 여기 있어!" 하고 응답하는 과정을 정해둔 규칙입니다.

HTTP는 주로 TCP 위에서 동작하며(기본 포트 80번), 요청(Request)과 응답(Response)이라는 단순한 구조로 이루어져 있습니다.

HTTP의 주요 특징 🔗


🚀

HTTP 요청 (Request) 🔗

클라이언트(웹 브라우저)가 서버에게 무언가를 요청할 때 보내는 메시지입니다. HTTP 요청은 크게 세 부분으로 구성됩니다.
  1. 시작 줄 (Start Line / Request Line)
    • 요청의 첫 번째 줄로, 세 가지 정보로 이루어집니다.
    • HTTP 메서드 (Method)
      요청의 종류를 나타냅니다. (예: GET, POST)
    • 요청 대상 (Request Target/URI)
      요청하는 자원의 경로입니다. (예: /index.html)
    • HTTP 버전 (HTTP Version)
      사용된 HTTP 프로토콜의 버전입니다. (예: HTTP/1.1)
    • 예시: GET /users/123 HTTP/1.1
  2. 헤더 (Headers)
    • 요청에 대한 추가 정보를 담고 있는 여러 줄의 키-값(Key-Value) 쌍입니다.
    • Host
      요청하는 서버의 호스트 이름과 포트 번호.
      (예: Host: www.example.com)
    • User-Agent
      요청하는 클라이언트(브라우저)의 정보.
      (예: User-Agent: Chrome/90.0...)
    • Accept
      클라이언트가 이해할 수 있는 콘텐츠 타입.
      (예: Accept: text/html)
    • Content-Type
      요청 본문의 데이터 타입 (주로 POSTPUT 요청 시 사용).
      (예: Content-Type: application/json)
    • 그 외에도 다양한 헤더들이 있습니다.
  3. 본문 (Body / Payload)
    • 요청을 통해 서버에 전달할 실제 데이터입니다. (주로 POST, PUT 요청 시 사용)
    • GET 요청은 보통 본문이 없습니다.

HTTP 요청 예시 🔗

GET /api/users?id=123 HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: application/json

🚀

HTTP 응답 (Response): "네, 요청하신 자료 여기 있습니다!" 🔗

서버가 클라이언트의 요청을 처리하고 그 결과를 돌려줄 때 보내는 메시지입니다. HTTP 응답도 요청과 유사하게 세 부분으로 구성됩니다.
  1. 상태 줄 (Status Line)
    • 응답의 첫 번째 줄로, 세 가지 정보로 이루어집니다.
    • HTTP 버전 (HTTP Version)
      사용된 HTTP 프로토콜의 버전. (예: HTTP/1.1)
    • 상태 코드 (Status Code)
      요청 처리 결과를 나타내는 세 자리 숫자. (예: 200)
    • 상태 메시지 (Reason Phrase / Status Text)
      상태 코드를 사람이 이해하기 쉽게 설명하는 짧은 글. (예: OK)
    • 예시
      HTTP/1.1 200 OK
  2. 헤더 (Headers)
    • 응답에 대한 추가 정보를 담고 있는 여러 줄의 키-값 쌍입니다.
    • Content-Type
      응답 본문의 데이터 타입. (예: Content-Type: text/html; charset=UTF-8)
    • Content-Length
      응답 본문의 길이 (바이트 단위).
    • Server
      응답을 생성한 웹 서버 소프트웨어의 정보.
    • Date
      응답 메시지가 생성된 날짜와 시간.
    • 그 외에도 다양한 헤더들이 있습니다.
  3. 본문 (Body / Payload)
    • 클라이언트에게 전달할 실제 데이터입니다. (예: HTML 코드, JSON 데이터, 이미지 파일 등)

HTTP 응답 예시 🔗

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 85
 
{
  "id": 123,
  "name": "홍길동",
  "email": "hong@example.com"
}

🚀

실습: Python requests 라이브러리로 HTTP 요청 보내고 응답 받기 🔗

Python의 requests 라이브러리는 HTTP 통신을 매우 쉽게 만들어줍니다.
간단한 GET 요청을 보내고 응답을 확인해 봅시다.
먼저 다음 명령어로 라이브러리를 설치해야 합니다.
pip install requests
이제 아래 코드를 실행해 보세요.
import requests # requests 라이브러리 임포트
 
  # 가상의 공개 API URL (JSONPlaceholder는 테스트용 공개 API를 제공합니다)
url = "https://jsonplaceholder.typicode.com/todos/1"
 
try:
    # 1. GET 요청 보내기
    response = requests.get(url)
    
    # 요청이 성공했는지 확인 (200번대 상태 코드이면 성공)
    # .raise_for_status()는 4xx 또는 5xx 응답을 받으면 HTTPError 예외를 발생시킵니다.
    response.raise_for_status() 
 
    # 2. 요청 정보 일부 확인 (requests 라이브러리가 만든 요청 객체)
    print("--- 요청 정보 ---")
    print(f"요청 방식: {response.request.method}") # 보낸 요청의 메서드 (GET)
    print(f"요청 URL: {response.request.url}")    # 보낸 요청의 URL
    # 요청 헤더는 딕셔너리처럼 접근 가능합니다.
    print(f"요청 User-Agent: {response.request.headers.get('User-Agent')}") 
 
    # 3. 응답 정보 확인
    print("\n--- 응답 정보 ---")
    print(f"상태 코드: {response.status_code}") # 응답 상태 코드 (예: 200)
    # 응답 헤더도 딕셔너리처럼 접근 가능합니다.
    print(f"응답 Content-Type: {response.headers.get('Content-Type')}") 
    
    # 4. 응답 본문 확인 (JSON 형식으로 가정)
    # .json() 메서드는 응답 본문이 JSON일 경우 파이썬 딕셔셔너리 또는 리스트로 변환해줍니다.
    todo_data = response.json() 
    print(f"응답 본문 (JSON): {todo_data}")
    # 딕셔너리에서 특정 키의 값을 가져옵니다.
    print(f"할 일 제목: {todo_data.get('title')}")
 
except requests.exceptions.HTTPError as http_err:
    # HTTP 오류 (4xx, 5xx) 발생 시
    print(f"HTTP 오류 발생: {http_err}") 
except requests.exceptions.ConnectionError as conn_err:
    # 네트워크 연결 관련 오류 발생 시
    print(f"연결 오류 발생: {conn_err}")
except requests.exceptions.Timeout as timeout_err:
    # 요청 시간 초과 오류 발생 시
    print(f"시간 초과 오류 발생: {timeout_err}")
except requests.exceptions.RequestException as req_err:
    # 그 외 requests 라이브러리 관련 오류 발생 시
    print(f"요청 중 알 수 없는 오류 발생: {req_err}") 
실행 결과
--- 요청 정보 ---
요청 방식: GET
요청 URL: https://jsonplaceholder.typicode.com/todos/1
요청 User-Agent: python-requests/2.32.3
 
--- 응답 정보 ---
상태 코드: 200
응답 Content-Type: application/json; charset=utf-8
응답 본문 (JSON): {'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}
할 일 제목: delectus aut autem
위 코드는 jsonplaceholder.typicode.com이라는 공개 API에 GET 요청을 보내고, 요청 정보 일부와 응답 상태 코드, 헤더, 그리고 JSON 형식의 본문을 출력합니다.
다양한 예외 처리 구문을 추가하여 실제 상황에서 발생할 수 있는 오류들에 대비하는 모습도 보여줍니다.

🚀

HTTP 상태 코드 🔗

HTTP 상태 코드는 서버가 클라이언트의 요청을 어떻게 처리했는지 알려주는 세 자리 숫자입니다. 마치 서버가 우리에게 보내는 짧은 메시지와 같습니다. 주요 그룹은 다음과 같습니다.
HTTP 상태 코드
HTTP 상태 코드

🚀

HTTPS (HyperText Transfer Protocol Secure) 🔗

HTTP는 데이터를 암호화하지 않고 평문(plaintext)으로 전송하기 때문에, 중간에 누군가가 데이터를 엿보거나(도청), 변조할 위험이 있습니다.
특히 로그인 정보, 개인 정보, 금융 정보 등을 주고받을 때는 매우 위험합니다.

이러한 HTTP의 보안 문제를 해결하기 위해 등장한 것이 바로
HTTPS
입니다.
HTTPS는 HTTP에
SSL(Secure Sockets Layer)
또는
TLS(Transport Layer Security)
라는 보안 계층을 추가한 것입니다.
SSL/TLS는 데이터를 암호화하여 안전하게 주고받을 수 있도록 해줍니다.

SSL/TLS: HTTPS를 안전하게 만드는 보안 프로토콜 🔗

SSL(현재는 TLS가 더 많이 사용됨)은 클라이언트와 서버 간의 통신을 암호화하여 제3자가 데이터를 훔쳐보거나 변경하는 것을 방지합니다.
주요 기능은 다음과 같습니다.

SSL/TLS 핸드셰이크: 안전한 통로 만들기 🔗

HTTPS 통신을 시작하기 전에, 클라이언트와 서버는 SSL/TLS 핸드셰이크라는 과정을 통해 안전한 연결을 설정합니다. 이 과정은 조금 복잡하지만, 간단하게 설명하면 다음과 같습니다.
  1. Client Hello
    클라이언트가 서버에게 "안녕? 나랑 안전하게 통신하고 싶어. 내가 지원하는 암호화 방식은 이런 것들이야." 하고 메시지를 보냅니다.
  2. Server Hello & Certificate
    서버는 "안녕! 네가 제안한 방식 중에 이걸로 하자. 그리고 내가 진짜 안전한 서버라는 증거로 내 SSL 인증서를 줄게." 하고 응답하며 자신의 SSL 인증서를 보냅니다.
  3. Certificate Verification & Key Exchange
    클라이언트는 서버의 인증서가 신뢰할 수 있는 인증기관(CA)으로부터 발급되었는지 확인합니다.
    확인이 끝나면, 실제 데이터 암호화에 사용할 비밀키(대칭키)를 생성하고, 이를 서버의 공개키로 암호화하여 서버에게 전달합니다.
  4. Secure Connection Established
    서버는 자신의 개인키로 암호화된 비밀키를 해독합니다.
    이제 클라이언트와 서버는 동일한 비밀키를 공유하게 되었고, 이 키를 사용하여 모든 데이터를 암호화하고 복호화하며 안전하게 통신합니다.
  5. Finished
    양쪽 모두 "이제 안전한 연결이 준비됐어!" 하고 확인 메시지를 주고받으면 핸드셰이크가 완료됩니다.
웹 브라우저 주소창에 자물쇠 아이콘(🔒)이 표시되면 HTTPS로 안전하게 연결되었다는 의미입니다.
SSL/TLS 핸드셰이크
SSL/TLS 핸드셰이크

🚀

결론 🔗

오늘은 웹 핵심 프로토콜인 HTTP와 그 안전한 버전인 HTTPS에 대해 알아보았습니다.
HTTP는 요청과 응답이라는 간단한 구조로 동작하며, 다양한 상태 코드를 통해 서버의 처리 결과를 알려줍니다.
HTTPS는 SSL/TLS를 통해 데이터를 암호화하여 우리가 안심하고 웹을 사용할 수 있도록 해줍니다. Python의 requests 라이브러리를 통해 간단한 HTTP 요청 실습도 해보았습니다.

우리가 만드는 웹 서비스가 사용자와 안전하게 소통하기 위해서는 HTTP와 HTTPS에 대한 정확한 이해가 필수적입니다.
다음 시간에는 우리가 www.google.com 같은 도메인 이름을 입력했을 때, 이것이 어떻게 실제 서버의 IP 주소로 바뀌는지, 그 비밀을 풀어줄 DNS 시스템에 대해 알아보겠습니다.

참고 🔗