HTTP/HTTPS는 인터넷과 모바일 애플리케이션의 모든 통신의 기초를 이루는 기본적인 데이터 전송 프로토콜입니다. HTTP(HyperText Transfer Protocol)는 클라이언트와 서버 간 요청 및 응답의 형식을 정의하며, HTTPS(HTTP Secure)는 TLS(Transport Layer Security) 또는 SSL(Secure Sockets Layer) 프로토콜을 통한 암호화를 추가합니다. Google 투명성 보고서(2025)에 따르면 전 세계 웹 트래픽의 95% 이상이 이미 HTTPS를 사용하고 있으며, Chrome 및 Safari와 같은 브라우저는 HTTP 사이트를 안전하지 않음으로 표시합니다. HTTP와 HTTPS의 차이점, 요청 구조 및 상태 코드를 이해하는 것은 네트워크 요청을 다루는 모든 모바일 앱 개발자에게 필수 최소 사항입니다.
핵심 사항
HTTP(HyperText Transfer Protocol)는 월드 와이드 웹에서 하이퍼텍스트 문서 및 기타 데이터를 전송하기 위해 설계된 OSI 모델의 애플리케이션 계층 프로토콜입니다. 1989년 Tim Berners-Lee가 개발한 HTTP는 HTTP/0.9(GET 요청과 HTML 응답만 가능)부터 최신 HTTP/2 및 HTTP/3까지 여러 버전을 거쳐왔습니다. 이 프로토콜은 요청-응답 모델로 작동합니다: 클라이언트가 서버에 요청을 보내면 서버가 이를 처리하고 응답을 반환합니다.
HTTPS(HTTP Secure)는 TLS(Transport Layer Security)를 통해 암호화 계층을 추가하는 HTTP 프로토콜의 확장입니다. HTTPS는 별도의 프로토콜이 아니라 HTTP와 TLS의 조합입니다. HTTPS를 통해 전송되는 데이터는 클라이언트 측에서 암호화되고 서버에서 복호화되어 가로채기 및 변조가 불가능합니다. HTTPS는 또한 SSL/TLS 인증서를 통해 서버 인증을 제공하여 클라이언트가 공격자가 아닌 실제 서버에 연결하고 있음을 보장합니다.
HTTP와 HTTPS의 주요 차이점은 보안입니다. HTTP는 데이터를 평문으로 전송하므로 클라이언트와 서버 사이의 모든 네트워크 노드가 요청 또는 응답의 내용을 읽을 수 있습니다. HTTPS는 URL, 헤더 및 요청 본문을 포함한 모든 콘텐츠를 암호화하여 서버의 IP 주소와 연결 포트만 표시합니다. 공용 Wi-Fi 네트워크를 통해 작동하는 모바일 애플리케이션의 경우 HTTPS는 필수 보안 요구 사항입니다.
HTTP는 TCP/IP 위에서 작동하는 상태 비저장(stateless) 프로토콜입니다. 클라이언트는 서버와 TCP 연결을 설정하고(일반적으로 HTTP는 포트 80, HTTPS는 포트 443), HTTP 요청을 보내고, HTTP 응답을 받은 후 연결을 종료합니다(HTTP/1.1에서는 연결을 재사용할 수 있음). 클라이언트와 서버 간의 각 상호 작용은 요청과 응답으로 구성됩니다. 상태 비저장이라는 것은 서버가 이전 클라이언트 요청에 대한 정보를 저장하지 않음을 의미하며, 각 요청은 독립적으로 처리됩니다.
HTTP 상호 작용 프로세스에는 다음 단계가 포함됩니다:
HTTP의 중요한 특성은 메서드 멱등성입니다. GET, HEAD, PUT, DELETE 및 OPTIONS는 멱등적입니다: 동일한 요청을 반복 실행해도 첫 실행 후 서버 상태가 변경되지 않습니다. POST, PATCH 및 CONNECT는 멱등적이지 않으며, 각 호출이 새 리소스를 만들거나 상태를 변경할 수 있습니다. 모바일 개발에서 멱등성 이해는 중요합니다: 네트워크 오류로 인해 요청을 재전송할 때 클라이언트는 요청을 반복해도 안전한지 알아야 합니다.
HTTPS는 전송 데이터를 보호하기 위해 암호화 프로토콜 TLS(Transport Layer Security)를 사용합니다. TLS는 1995년 Netscape가 개발한 SSL(Secure Sockets Layer)의 후속 버전입니다. SSL 2.0 및 3.0은 구식이며 안전하지 않은 것으로 간주되며, 최신 TLS 1.2(2008년 출시) 및 TLS 1.3(2018년 출시)이 널리 사용됩니다. 특히 TLS 1.3은 연결 설정 시간을 2회 왕복에서 1회로 줄여 모바일 장치에서 로딩을 크게 가속화합니다.
TLS 핸드셰이크 프로세스에는 다음 단계가 포함됩니다:
SSL/TLS 인증서 확인은 보안상 중요한 단계입니다. 클라이언트는 인증서가 만료되지 않았고, 신뢰할 수 있는 인증 기관(CA)에 의해 서명되었으며, URL의 도메인과 일치하고, 폐기되지 않았는지(CRL 또는 OCSP 통해) 확인합니다. 모바일 애플리케이션에서는 인증서 고정(Certificate Pinning)을 사용하는 것이 좋습니다. 이는 특정 서버 인증서 또는 공개 키에 바인딩하는 것입니다. 이는 CA가 손상되더라도 MITM 공격을 방지합니다. 그러나 인증서 고정에는 주의가 필요합니다: 인증서가 변경되면 애플리케이션을 사전에 업데이트해야 합니다.
HTTP 요청은 요청 라인, 헤더 및 선택적 본문의 세 부분으로 구성됩니다. 요청 라인에는 HTTP 메서드, 요청 URL 및 HTTP 버전이 포함됩니다. 헤더는 메타 정보(콘텐츠 유형, 인증 토큰, 캐싱 설정)를 전송합니다. 본문은 데이터를 전송하는 메서드(POST, PUT, PATCH)에만 존재하며 GET 및 DELETE에는 없습니다.
REST API에 대한 HTTP 요청 예시:
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Cache-Control: no-cache
{
"name": "안나",
"email": "anna@example.com"
}
HTTP 응답도 유사한 구조를 가집니다: HTTP 버전과 상태 코드가 포함된 상태 라인, 헤더 및 본문입니다. 상태 코드는 요청 처리 결과를 결정하는 세 자리 숫자입니다. 응답 헤더에는 Content-Type, Content-Length, Cache-Control, Set-Cookie 등이 포함됩니다. 응답 본문에는 Content-Type에 지정된 형식(일반적으로 API의 경우 JSON, 웹 페이지의 경우 HTML, 미디어 콘텐츠의 경우 이미지)의 요청된 데이터가 포함됩니다.
헤더는 HTTP 작동에서 중요한 역할을 합니다. Content-Type과 Accept는 데이터 형식을 제어합니다. Authorization은 액세스 토큰을 전송합니다. Cache-Control은 캐싱을 관리합니다. CORS 헤더(Access-Control-Allow-Origin)는 브라우저에서 다른 도메인의 액세스를 제어합니다. User-Agent는 클라이언트 애플리케이션을 식별합니다. 모바일 애플리케이션의 경우 캐시 제어 헤더가 특히 중요합니다: 전송 데이터 양을 줄이고 약한 신호에서 성능을 개선하는 데 도움이 됩니다.
HTTP 상태 코드는 첫 번째 숫자로 표시되는 다섯 가지 클래스로 그룹화됩니다: 1xx(정보), 2xx(성공), 3xx(리디렉션), 4xx(클라이언트 오류), 5xx(서버 오류). 이러한 코드를 이해하는 것은 모바일 애플리케이션에서 응답을 올바르게 처리하는 데 필요합니다: 2xx는 성공을 의미하며 데이터를 표시할 수 있고, 4xx는 요청에 문제가 있음을 나타내며(사용자에게 오류 표시), 5xx는 서버 문제를 나타냅니다(나중에 요청 재시도).
| 코드 | 이름 | 설명 | 클라이언트 조치 |
|---|---|---|---|
| 200 | OK | 성공적인 요청 | 데이터 처리 |
| 201 | Created | 리소스 생성됨 | UI 업데이트 |
| 301 | Moved Permanently | 리소스가 새 URL로 이동됨 | 코드의 URL 업데이트 |
| 400 | Bad Request | 잘못된 요청 | 유효성 검사 오류 표시 |
| 401 | Unauthorized | 인증 필요 | 로그인으로 리디렉션 |
| 404 | Not Found | 리소스를 찾을 수 없음 | 404 표시 |
| 429 | Too Many Requests | 요청 한도 초과 | 지연 후 재시도 |
| 500 | Internal Server Error | 서버 오류 | 나중에 재시도 |
모바일 애플리케이션의 경우 401 Unauthorized 코드 처리가 특히 중요합니다. 이 코드를 수신하면 클라이언트는 리프레시 토큰을 사용하여 액세스 토큰을 갱신하고 원래 요청을 재시도해야 합니다. 토큰 갱신도 401을 반환하면 사용자를 로그인 화면으로 리디렉션해야 합니다. 이 로직은 일반적으로 인터셉터(OkHttp) 또는 네트워크 클라이언트의 미들웨어 계층에서 구현됩니다.
HTTP/1.1(1999년 출시)은 여전히 널리 사용되는 프로토콜 버전입니다. 주요 단점은 헤드 오브 라인 블로킹입니다: 동일한 서버에 대한 요청이 순차적으로 실행되며 각 요청은 이전 요청이 완료될 때까지 기다립니다. 이 제한을 우회하기 위해 브라우저는 동일한 도메인에 6~8개의 병렬 TCP 연결을 열어 서버 부하와 메모리 소비를 증가시킵니다. HTTP/1.1은 또한 헤더를 평문으로 전송하며 서버 푸시를 지원하지 않습니다.
HTTP/2(2015)는 멀티플렉싱을 통해 블로킹 문제를 해결합니다: 여러 데이터 스트림이 단일 TCP 연결을 통해 동시에 전송됩니다. 서버는 클라이언트가 요청하기 전에 리소스를 보낼 수 있습니다(서버 푸시). HTTP/2는 또한 HPACK을 사용하여 헤더를 압축하여 전송 데이터 양을 줄입니다. 모바일 애플리케이션의 경우 HTTP/2가 특히 유용합니다: 하나의 연결이 여러 연결을 대체하여 TLS 핸드셰이크 시간과 배터리 소비를 줄입니다.
HTTP/3(2022)는 TCP 대신 QUIC(Quick UDP Internet Connections)을 사용하는 프로토콜의 최신 버전입니다. QUIC은 UDP 위에서 작동하여 전송 프로토콜 수준에서 헤드 오브 라인 블로킹 문제를 제거합니다. HTTP/3는 최상의 경우(재연결 시) 연결 설정 시간을 0회 왕복으로, 첫 연결 시 1회 왕복으로 줄여 2~3회 왕복이 필요한 HTTP/2보다 훨씬 빠릅니다. 모바일 장치의 경우 HTTP/3는 Wi-Fi와 모바일 네트워크 간 전환 시 특히 효과적입니다: QUIC이 IP 주소 대신 연결 식별자를 사용하므로 연결이 끊어지지 않습니다.
모바일 애플리케이션에서 HTTPS 사용은 권장 사항이 아니라 필수 요구 사항입니다. Android 9(API 28) 및 iOS 9(ATS — App Transport Security)부터 모든 네트워크 요청은 기본적으로 HTTPS를 사용해야 합니다. HTTP 요청은 시스템에 의해 차단되며, 이를 허용하려면 애플리케이션 구성에서 명시적 예외가 필요합니다. Google Play 스토어와 App Store는 비밀번호, 토큰 및 개인 데이터를 포함한 민감한 데이터를 HTTP로 전송하는 애플리케이션을 거부합니다.
Android 모바일 애플리케이션의 HTTPS 구성은 다음을 포함합니다:
<!-- AndroidManifest.xml — 네트워크 요청 권한 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- network_security_config.xml — HTTPS 구성 -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-12-31">
<pin digest="SHA-256">rDjsFv3bGf...</pin>
</pin-set>
</domain-config>
</network-security-config>
iOS에서는 NSAppTransportSecurity 키를 사용하여 Info.plist를 통해 유사한 구성이 이루어집니다. 모바일 애플리케이션에서 HTTPS 트래픽을 디버깅하기 위해 프록시 도구(Charles Proxy, Proxyman 또는 mitmproxy)가 사용됩니다. 이들은 장치에 신뢰할 수 있는 SSL 인증서를 설치해야 합니다. 프로덕션 빌드에서는 디버깅 기능을 비활성화하고 인증서 고정이 올바르게 구성되었는지 확인해야 합니다. Android에서 CertificatePinner를 사용하는 OkHttp 또는 iOS에서 SecTrustEvaluate를 사용하는 TrustManager는 인증서 고정을 구현하는 표준 접근 방식입니다.
모바일 개발에서 HTTPS의 중요한 보안 측면은 SSL 고정(SSL Pinning)입니다. 고정이 없으면 애플리케이션은 알려진 CA가 서명한 모든 인증서를 신뢰합니다. CA가 손상되면 공격자가 애플리케이션의 트래픽을 가로챌 수 있습니다. 고정은 애플리케이션을 특정 서버 인증서 또는 공개 키에 바인딩합니다. 서버 인증서가 변경되면 애플리케이션 업데이트를 출시해야 하므로 고정은 여유를 두고 계획됩니다(상위 CA 인증서에 바인딩하거나 여러 백업 키 사용).
자주 묻는 질문
HTTP는 데이터를 평문으로 전송하고, HTTPS는 TLS/SSL을 통해 트래픽을 암호화합니다. HTTPS는 포트 443을 사용하고 HTTP는 포트 80을 사용합니다. HTTPS에는 SSL 인증서가 필요하며 기밀성, 무결성 및 서버 인증을 제공합니다.
네, Android 9 및 iOS 9부터 HTTPS는 기본적으로 의무입니다. 구성에서 명시적으로 허용되지 않는 한 HTTP 요청은 시스템에 의해 차단됩니다. 앱 스토어는 민감한 데이터를 전송하는 모든 네트워크 요청에 HTTPS를 요구합니다.
SSL 인증서는 서버의 신뢰성을 확인하는 디지털 문서입니다. 인증 기관(CA)에서 발급합니다: Let's Encrypt(무료), Sectigo, DigiCert. 개발용으로는 자체 서명된 인증서를 사용할 수 있습니다.
HTTP/2는 멀티플렉싱(단일 TCP 연결을 통한 여러 요청), 헤더 압축(HPACK) 및 서버 푸시를 지원합니다. 요청이 서로를 차단하는(헤드 오브 라인 블로킹) HTTP/1.1과 달리 HTTP/2는 데이터를 병렬로 전송합니다.
인증서 고정(Certificate Pinning)은 애플리케이션이 특정 인증서 또는 공개 키만 신뢰하는 보안 기술입니다. 높은 보안 요구 사항(은행, 결제, 의료 데이터)이 있는 애플리케이션에 권장됩니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.