[iOS] [AWS] 早い!安い!美味い!Amazon CloudFrontをプロキシにして最速ATS対応!

2016.11.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

おばんです、帰省する時期も近づいてきて実家の父から赤羽にある伊勢屋という和菓子屋で塩大福をお土産に欲しい欲しい欲しい欲しいと言われてまいっている田中です。
でも確かにここの塩大福は肉厚で、美味しい。こういうのが良いんだ。


さて、iOSエンジニアの皆さんは2016年末までに、アプリと接続するネットワークの間で行われる通信がセキュアな通信であることを保証する、ATSという機能に対応をする必要があるのはもうご存知のことでしょう。

今日はその対応策としてAWSのCloudFrontをプロキシとして利用すると捗るかもしれない!という話をまとめます。
元ネタは以下のスライドです。

対象読者

  • これからATS対応をするiOSエンジニアの方
  • iOSアプリ向けのWebAPIの運用されているバックエンドエンジニアの方

特に今回紹介するCloudFrontを使った手法は個人で開発をしているアプリをATS対応させるためにも有用な手段です。
AWSになじみのないiOSエンジニアの方でも簡単なものであれば時間をかけずにATS対応を完了させることができるかもしれません。オススメです。

CloudFrontとはなにか?

Storage-Content-Delivery_AmazonCloudFront

「iOSエンジニアなのでAWSについては知りません!」という方もいらっしゃるかもしれません。
僕もその一人なので、軽く概要について触れます。

CloudFrontはAWSの製品の一つで、役割は以下の二つです。

  • エッジサーバーでのキャッシュを利用した静的コンテンツの高速配信
  • 動的コンテンツへのプロキシ(今回はコッチ)

今回はアプリで直接HTTP通信をオリジンサーバーとするとATSに引っかかってしまうので、下図のようにアプリとオリジンサーバーの間にCloudFrontをプロキシとして置いて、アプリからはCloudFrontに対してリクエストを出すという作りの説明です。

スクリーンショット 2016-11-25 16.13.20

CloudFrontを用いるとなにが良いのか?

Gyuu-don_002

CloudFrontをATS対応のためのプロキシとして利用するメリットは三つあります。
そのメリットはズバリ、早い!安い!美味い!

早い

CloudFrontにアプリで使用するサーバーをオリジンサーバーとして登録し、SSL CertificateをDefault CloudFront Certificateというデフォルト設定をするだけでATS対応を終えることができます。
以上より時間的なコストを抑えることができます。

安い

上述したデフォルト設定の証明書か、あるいはAWS Certificate Managerで発行した証明書は無料です。
金銭的なコストを抑えることができます。

美味い

プロキシとして利用する以外の役割、もともとのCloudFrontの強みとなるエッジサーバーでのキャッシュを利用したコンテンツの高速配信ができる機能のおかげでリソースへのアクセスが早くなります。

どんなときに使えるか、使えないか

CloudFrontにサーバーをオリジンサーバーとして登録する都合上、CloudFrontをプロキシとして扱うためには主に数の観点で可否が分かれます。

使える場合

  • アプリからの接続先のドメインの数が限られている場合

使えない場合

  • アプリからの接続先のドメインが動的でその数を特定しきれない場合

iOSの検証

スクリーンショット 2016-11-25 16.31.54

上の構成図でCloudFrontを利用した場合のATSの挙動を検証しましたのでこちらに記載します。
検証内容はATSを有効にした状態でのWebView、URLSessionによる通信です。

検証環境

  • iOS 9.3, 10.1 シミュレータ
  • Xcode 8.1
  • Info.plistでNSAppTransportSecurityのDictionaryの中にNSAllowsArbitraryLoadsがNOに設定されている
  • Info.plistでNSAppTransportSecurityのaryの中にNSAllowsArbitraryLoadsInWebContentがNOに設定されている

検証結果

URLSessionによる通信

利用クラスとOSバージョン オリジンサーバーに直接httpで接続を試みる CloudFrontにhttpsで接続を試みる
URLSession(iOS 9) NG OK
URLSession(iOS 10) NG OK

WebViewによる通信

利用クラスとOSバージョン オリジンサーバーに直接httpで接続を試みる CloudFrontにhttpsで接続を試みる CloudFrontにhttpsで接続した先でさらに別ドメインへのWeb遷移をする
UIWebView(iOS 9) NG OK NG
UIWebView(iOS 10) NG OK NG
WKWebView(iOS 9) NG OK NG
WKWebView(iOS 10) NG OK NG

「CloudFrontにhttpsで接続した先でさらに別ドメインへのWeb遷移をする」の項目は、CloudFrontから直接遷移したWebページ上にある、外部遷移するHTMLリンクなどの検証を指します。
もちろんそれはCloudFrontを介した通信ではないため、ATSではじかれる結果となりました。

まとめ

CloudFrontをプロキシとして利用するのに適した具体的なシーン

  • 自前でも自前でないものでも問わず、WebAPIへのアクセス
  • WebブラウジングをしないWebView
  • 遷移先の限られたWebページの表示
    • 利用規約ページ
    • コンタクトページ

などが考えられます。

例えば遷移した先が商品詳細ページでその商品に関連した商品ページに遷移して表示したり、Webページが自分たちで用意したサーバーから提供されるものでない場合はこのCloudFrontを利用したプロキシは適しません。
今後そのような場合にWebViewを利用した実装はリスクとなってくるのかもしれません。

その場合はSFSafariViewControllerを利用するかSafariで表示させる方法が取れますが、アフィリエイトが関係する場合や、アプリで取得したセッション情報を利用する場合には別途それも考慮する必要がありますので、注意してください。

自前でないWebAPIへのアクセスのプロキシとして使えるという点は、自前以外のデータをデータソースとして利用しているアプリを救う手段にもなるのでとても有用です。

試してみての感想

どちらかというとサーバーサイドエンジニアの担当領域かもしれませんが、AWSやサーバーサイドに明るくない自分でも環境構築をすることができたので利用しやすさという点でもオススメです。
少しでもATS対応の闇から救われる方が増えれば幸いです。m(_ _)m

参考