WWDC 15 提出的 ATS (App Transport Security) 是 Apple 在推进网络通讯安全的一个重要方式。在 iOS 9 和 OS X 10.11 中,默认情况下非 HTTPS 的网络访问是被禁止的。当然,因为这样的推进影响面非常广,作为缓冲,我们可以在 Info.plist 中添加 NSAppTransportSecurity 字典并且将 NSAllowsArbitraryLoads 设置为 YES 来禁用 ATS。相信大家都已经对这个非常熟悉了,

不过,WWDC 16 中,Apple 表示将继续在 iOS 10 和 macOS 10.12 里收紧对普通 HTTP 的访问限制。从 2017 年 1 月 1 日起,所有的新提交 app 默认是不允许使用 NSAllowsArbitraryLoads 来绕过 ATS 限制的,也就是说,我们最好保证 app 的所有网络请求都是 HTTPS 加密的,否则可能会在应用审核时遇到麻烦。 对于 API 请求,基本上是必须使用 HTTPS 的,Transport Layer Security协议版本要求TLS1.2以上

下面就来一起看看具体的切换步骤吧。

0.准备工作

购买Https证书,我是在godaddy上买的,买完对照他们的文档配置在服务器上。

  • 下载证书

  • 得到两个文件,并双击打开他们

  • 然后到keychain里导出.cer文件,后面会用到

1.IOS App端修改与配置

  • 把刚才的cer证书文件导入到项目中:

  • AFNetworking3.x配置ATS

NSString *cerPath = [[NSBundle mainBundle] pathForResource:@”https” ofType:@”cer”];
NSData * certData =[NSData dataWithContentsOfFile:cerPath];
NSSet * certSet = [[NSSet alloc] initWithObjects:certData, nil];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy 	policyWithPinningMode:AFSSLPinningModeCertificate];
// 是否允许,NO-- 不允许无效的证书
[securityPolicy setAllowInvalidCertificates:YES];
// 设置证书
[securityPolicy setPinnedCertificates:certSet];

manager.securityPolicy  = securityPolicy;
  • 项目.plist设置 ,Allow Arbitrary Loads设置为NO,因为项目中有图片、语音是在其它服务器上的,与API不是在同一个服务品。所以需要单独配置一下支持Http,这个苹果审核是允许的。

2.服务端修改与配置

  • 检查https网站是否通过TLSV1.2,通过以下命令:

      nscurl --ats-diagnostics --verbose https://secure.getgaoding.com
    

  • Nginx配置,开启TLSv1.2 修改nginx下的配置文件conf/nginx.conf

      server {
      listen       443;
      server_name  secure.getgaoding.com;
      access_log  /get/log/nginx/secure/secure.access.log  main;
      ssl on;
      ssl_certificate      /usr/local/nginx/secure.getgaoding.com_combined.crt;
      ssl_certificate_key  /usr/local/nginx/secure.getgaoding.com.key;
      ssl_session_timeout  5m;
      ssl_protocols  SSLv2 SSLv3 TLSv1 TLSv1.2 TLSv1.1;
      ssl_ciphers  HIGH:!aNULL:!MD5;
      ssl_prefer_server_ciphers   on;
    
      location ~* ^/user/* {
          proxy_pass http://userapi;
      }
    
      location ~* ^/sender/* {
          proxy_pass http://send;
      }
    
      location / {
          root   html;
          index  index.html index.htm;
      }
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          root   html;
      }   }
    

3.搞定!