转载自:swift cafe

使用
NSURLSession

NSURLSession 是 iOS 原生提供的网络处理库。它提供了丰富的接口以及配置选项,满足我们平时网络处理的大部分需求,同时它也支持 https。关于 NSURLSession 的基本内容,可以参看之前的这篇文章:

NSURLSession 网络库

这次我们主要介绍使用 NSURLSession 对 https 的处理,关于 https 的基本原理,大家可以参看这里:

Https 与 iOS 信息安全

好了,准备知识都了解了之后,我们就可以开始了。

NSURLSession 默认是支持 https 处理的, 包括证书验证, https 握手等操作, 都已经帮我们处理过了, 举个例子:

if let url = NSURL(string: "https://httpbin.org/get") {

    NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in

        print("%@",NSString(data: data!, encoding: NSUTF8StringEncoding))
//成功输出 }.resume() }

这里我们用 https 协议访问了一个地址。 就像访问普通的 http 地址一样, NSURLSession 的回调中成功的输出了返回的数据,我们完全没有进行任何的额外处理,就已经可以访问 https 地址了。

是的,这种情况对于服务器的证书正确的情况下,是没问题的。因为 NSURLSession 的内部处理机制中已经预置了可信任的根证书的。只要你访问的地址使用的 SSL证书,是用这些跟证书机构授权的,就不会有问题。

但还存在这样一种情况,就是如果你访问的地址所使用的证书,不是这些颁发机构授权的, 而是它们自己生成的(这也叫自签名证书), 问题就出现了。比如我们再用同样的 API 访问另一个地址:

if let url = NSURL(string: "https://www.pcwebshop.co.uk") {

    NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in

        //... 

    }.resume()

}

如果执行这段代码的话,你会在控制台中收到这样一个错误:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

很明显,SSL 证书验证失败了,并且这个时候 dataTaskWithURL 方法的回调闭包中,不会返回任何数据。 所以我们在设计客户端使用 https 协议进行交互的时候,虽然大部分逻辑 iOS 原生库都已经帮我们处理好了,但这种证书验证失败的情况还是需要大家注意一下的。

其实 iOS 默认的这种实现也是有一定道理的,证书验证失败的站点,从原则上来说是不可信,不安全的。 所以原生库在默认情况下拒绝这样的链接也是正确的。

自定义证书验证行为

我们平常使用的大多数浏览器也是有这样的逻辑的,如果发现证书验证失败,就会给用户提示一个警告,让用户选择是否要继续访问。 iOS 原生库的通用原则是拒绝一切未经验证的证书, 这种行为可以很好的保证用户的安全。

但是,我们有一些自己特定的需求怎么办呢, 比如我们自己的 app 接口使用的是 https 方位我们自己的服务器, 但我们自己的服务器使用的是自签名证书, 如果按照默认行为的话, 尽管我们自己确信这个自签名证书是安全的,接口的访问也永远不会成功。 因为它不在 iOS 原生库的信任列表中。

这时候,我们就需要更深入的处理证书验证的细节了, NSURLSession 也给我们提供了相应的 API。 要在这些 API 中加入我们自己的验证逻辑,我们需要实现 NSURLSessionDelegate 的 didReceiveChallenge 方法:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {

        let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential) } }

didReceiveChallenge 方法中,首先通过 authenticationMethod 属性检测服务端的验证方式, 只有是 NSURLAuthenticationMethodServerTrust 的时候我们才进行处理。 NSURLAuthenticationMethodServerTrust 代表的就是 https 验证。

再看一下 if 分支里面的处理, NSURLCredential(forTrust:
challenge.protectionSpace.serverTrust!)
 这里创建了一个授信,告诉系统服务器返回的这个证书是可信的。这样这个自签名的证书也能获得通过了。

再次运行程序,就可以看到这个自签名的地址能够正常访问了。

如果你是 iOS 9 以上的系统,还要记得修改一下 Info.plist 里面的 App Transport Security Settings 设置,在里面加上这一段即可:


<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

否则,这种请求也会被 iOS 的全局设置阻拦的。

iOS 原生库对 https 的处理的更多相关文章

  1. iOS 原生库(AVFoundation)实现二维码扫描,封装的工具类,不依赖第三方库,可高度自定义扫描动画及界面(Swift 4.0)

    Create QRScanner.swift file // // QRScanner.swift // NativeQR // // Created by Harvey on 2017/10/24. ...

  2. 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?【转载】

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...

  3. IOS第三方库 MARK

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...

  4. 你一定能用的上的iOS第三方库

    点国内程序员不常用的热门iOS第三方库:看完,还敢自称"精通iOS开发"吗? 综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型, ...

  5. 盘点国内程序员不常用的热门iOS第三方库

    https://github.com/syedhali/EZAudio 基于核心音频,有助于进行实时,低延迟音频处理和可视化的iOS和OSX音频可视化框架. https://github.com/ba ...

  6. iOS 开源库

    youtube下载神器:https://github.com/rg3/youtube-dl我擦咧 vim插件:https://github.com/Valloric/YouCompleteMevim插 ...

  7. iOS第三方库

    热门iOS第三方库:看完,还敢自称”精通iOS开发”吗? 综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? h ...

  8. 热门IOS 第三方库

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...

  9. iOS开源库--最全的整理

    youtube下载神器:https://github.com/rg3/youtube-dl我擦咧 vim插件:https://github.com/Valloric/YouCompleteMevim插 ...

随机推荐

  1. Ubuntu使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多字母解决方案

    原因是系统只装了vi,没有装vim.因为vi是不能直接按退格键删除字符的.所以重新装下vim指令即可: # sudo apt-get install vim 重新使用vi命令进行文件编辑.

  2. 【Unity与Android】02-在Unity导出的Android工程中接入Google Admob广告

    我在上一篇文章 [Unity与Android]01-Unity与Android交互通信的简易实现) 中介绍了Unity与Android通讯的基本方法. 这一篇开始进入应用阶段,这次要介绍的是如何在An ...

  3. mybatis执行过程及经典面试题

    Mybatis执行流程 mybatis中xml解析是通过SqlSessionFactoryBuilder.build()方法. 初始化mybatis(解析xml文件构建成Configuration对象 ...

  4. 一个PHP文件搞定微信H5支付

     / 更新于 2018-07-02 / 8 条评论 过年期间也坚持要撸码啊接着给博客除草,在这个小除夕是情人节的一天,祝大家新年快乐,情人节能够顺利脱单~~~ 回归正题,这篇文章介绍一下微信H5支付, ...

  5. JavaScript 面向对象编程 · 理解对象

    前言:      在我们深入 面向对象编程之前 ,让我们先理解一下Javascript的 对象(Object),我们可以把ECMAScript对象想象成散列表,其值无非就是一组名值对,其中值可以是数据 ...

  6. 五 mysql之多表查询

    目录 一 介绍 二 多表连接查询 1.交叉连接:不适用任何匹配条件.生成笛卡尔积 2.内连接:只连接匹配的行 3 .外链接之左连接:优先显示左表全部记录 4 .外链接之右连接:优先显示右表全部记录 5 ...

  7. 色即是空,空即是色---java有关null的几件小事

    故事背景 ---摩诃般若波罗蜜多心经: 观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄.舍利子,色不异空,空不异色:色即是空,空即是色.受想行识,亦复如是.舍利子,是诸法空相,不生不灭,不垢 ...

  8. selenium-webdriver中的显式等待与隐式等待

    在selenium-webdriver中等待的方式简单可以概括为三种: 1 导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2 隐式等待,直接调用i ...

  9. python编程基础之二十三

    集合:和数学里面完全一样的,不允许有重复元素,如果添加重复元素,就会被过滤,可以进行交并差的运算  集合是可变对象 本质:无需且无重复的数据结构 创建集合 s1 = set()  括号里面可以放可迭代 ...

  10. java的动手动脑10月20日

    (1)动手动脑 该函数没有赋初值再就是如果类提供一个自定义的构造方法,将导致系统不在提供默认的构造方法. (2) public class test { /*** @param args*/publi ...