Apple 为啥要强制使用HTTPS,在这里我不探讨,请自行Google或者度娘。
我在这里说说我们怎么去适配这条规则,以下个人见解,可能会存在不足,欢迎指出,一起进步。
- 其实我也是这两天才开始重视这件事情的,以前iOS9出的时候,当时为了偷懒(我们已经用的是HTTPS),就直接在info.iplist修改 NSAppTransportSecurity 这个属性,是这个样的:
<key>NSAppTransportSecurity</key>
<dict>
<!--彻底倒退回不安全的HTTP网络请求,能任意进行HTTP请求 (不建议这样做)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
在 plist 文件里显示如下:
直到前两天,有个同事(另一个项目组的)也是在做这个HTTPS的适配(马上就要2017了),他就直接修改info.plist的字段NSAllowsArbitraryLoads为NO,但是,这样做并不能访问我们API的地址,原因可能是:我们的证书是公司自检证书,不支持Certificate Transparency。如果你的证书是有CA颁发的支持Certificate Transparency,以下内容可以忽略。
好了说到这里,是可以进入正题了。
如果服务器不符合ATS要求,参照 官方文档 App Transport Security Technote 对ATS 的介绍。
比如当你遇到以下三个不符合ATS要求的服务器域名时:
1. api.xxxdomain.com
2. cdn.domain.com
3. otherdomain.com
这个时候我们可以针对不同域名作如下操作:
- api.xxxdomain.com
Info.plist 配置中的XML源码如下所示:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>api.xxxdomain.com</key>
<dict>
<!--允许App进行不安全的HTTP请求-->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--适用于这个特定域名下的所有子域-->
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
在 plist 文件里显示如下:
我们定义的第一个“例外”(Exception)告诉ATS当与这个子域交互时撤销了必须使用HTTPS的要求。注意这个仅仅针对在“例外”(Exception)中声明的子域。非常重要的一点是要理解NSExceptionAllowsInsecureHTTPLoads关键字并不仅仅只是与使用HTTPS相关,这个“例外”(EXception)指明了对于那个域名,所有的App Transport Security的要求都被撤销了。
- cdn.domain.com
Info.plist 配置中的XML源码如下所示:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>cdn.domain.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
在 plist 文件里显示如下:
很可能你的应用是与一个支持HTTPS传输数据的服务器交互,但是并没有使用TLS1.2或更高。在这种情况下,你定义一个例外(Exception),它指明应该使用的最小的TLS版本。这比完全撤销某个域名的App Transport Security要更好更安全。
- otherdomain.com
Info.plist 配置中的XML源码如下所示:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>otherdomain.com</key>
<dict>
<!--适用于这个特定域名下的所有子域-->
<key>NSIncludesSubdomains</key>
<true/>
<!--允许App进行不安全的HTTP请求-->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--在这里声明所支持的 TLS 最低版本-->
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
在 plist 文件里显示如下:
NSIncludesSubdomains
关键字告诉App Transport Security 这个“例外”(Exception)适用于这个特定域名的所有子域。
- 如果你的APP中同时用到了以上三个域名,那应该是这样:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>api.xxxdomain.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<false/>
</dict>
<key>cdn.domain.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
<key>otherdomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
以上是对三种不同域名的适配,参考这里原文.