
Expo Go 환경에서 개발하던 앱을 FCM(Firebase Cloud Messaging) 등의 네이티브 기능을 사용하기 위해 Expo Dev Client로 마이그레이션하는 과정에서 특이한 현상이 발생했습니다.
마이그레이션 후 API 요청에 문제가 생겼는데, 안드로이드 에뮬레이터에서는 API 요청이 정상 작동하는 반면, iOS 시뮬레이터에서는 모든 API 호출이 'Network Request Failed' 오류와 함께 실패했습니다.
더 이상한 점은 jsonplaceholder와 같은 공개 API는 iOS에서도 정상적으로 작동한다는 것이었습니다.
처음에는 CORS 설정이나 포트 제한, 또는 IP 차단 같은 문제를 의심했습니다.
코드는 기존과 동일하게 유지했으며, Swagger를 통해 서버가 정상 작동하는 것도 확인했습니다.
그러나 이것만으로는 왜 동일한 코드로 안드로이드에서는 작동하고 iOS에서는 작동하지 않는지 설명할 수 없었습니다.
문제를 분석하기 위해 여러 테스트를 진행했습니다:
테스트 결과, iOS에서는 HTTP 요청만 실패하고 HTTPS 요청은 정상 작동하는 패턴을 발견했습니다.
공개 API가 작동했던 이유도 대부분의 공개 API가 HTTPS를 사용하기 때문이었습니다.
이 문제를 해결하기 위해 백엔드 개발자에게 다음과 같은 정보를 공유했습니다:
URL: http://[서버IP]:[포트]/auth/login
Method: POST
Headers: Content-Type: application/json
Body: {"email": "test1234@gmail.com", "password": "test1234@"}
백엔드 개발자는 즉시 원인을 파악했습니다: "iOS에서는 보안상의 이유로 HTTP 요청을 차단하고 HTTPS 요청만 허용합니다. 안드로이드는 두 가지 방식을 모두 지원하지만, iOS는 HTTP 요청을 거부합니다."
이 문제는 iOS와 안드로이드의 보안 정책 차이에서 비롯되었습니다:
iOS: iOS 9부터 App Transport Security(ATS)가 도입되어 기본적으로 HTTP 통신이 차단되고 HTTPS만 허용됩니다. 이는 애플의 보안 강화 정책의 일환입니다.
안드로이드: 안드로이드도 HTTPS를 권장하지만, HTTP 통신도 기본적으로 허용합니다. 안드로이드 9(API 레벨 28) 이상에서는 기본적으로 cleartext HTTP 트래픽을 차단하는 설정이 도입되었지만, 많은 앱에서 여전히 예외를 허용하고 있습니다.
이 문제를 해결하기 위한 두 가지 접근법이 있습니다:
Info.plist 파일에 다음과 같은 설정을 추가하여 특정 도메인에 대한 HTTP 통신을 허용할 수 있습니다:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>13.125.58.70</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
이 방법은 개발 중에는 편리하지만, 앱스토어 심사 시 거부될 가능성이 있습니다.
애플은 특별한 이유가 없는 한 모든 네트워크 통신에 HTTPS를 사용할 것을 강력히 권장합니다.
더 나은 해결책은 백엔드 서버를 HTTPS로 업그레이드하는 것입니다. 이를 위해서는:
서버가 HTTPS로 업그레이드된 후에는 클라이언트 코드의 API 기본 URL을 변경해야 합니다:
// 변경 전
baseURL: "http://[서버IP]:[포트]"
// 변경 후
baseURL: "https://[서버IP]" // 또는 https://[서버IP]:[포트]
이 경험에서 얻은 몇 가지 중요한 교훈:
항상 HTTPS 사용하기: 개발 초기 단계부터 HTTPS를 사용하면 이런 문제를 미리 방지할 수 있습니다.
플랫폼별 차이 인지하기: iOS와 안드로이드는 보안 정책, UI 렌더링, 권한 관리 등 여러 측면에서 차이가 있습니다. 두 플랫폼 모두에서 테스트하는 것이 중요합니다.
백엔드-프론트엔드 협업: 이런 문제는 개발자 간의 원활한 의사소통으로 빠르게 해결할 수 있습니다.
보안 우선: 애플의 엄격한 정책은 사용자 보안을 위한 것이므로, 개발 편의성보다 보안을 우선시하는 접근 방식을 채택하는 것이 좋습니다.
HTTP와 HTTPS의 차이는 단순히 프로토콜의 차이가 아니라, 사용자 데이터를 보호하는 중요한 보안 요소입니다. 모바일 앱 개발에서는 처음부터 HTTPS를 사용하여 모든 플랫폼에서 일관된 경험을 제공하는 것이 좋겠습니다.