美文网首页ios知识
iOS网络(二)-HTTP、HTTPS

iOS网络(二)-HTTP、HTTPS

作者: 搬砖的crystal | 来源:发表于2021-10-15 15:25 被阅读0次

    一、URL

    URL的全称是Uniform Resource Locator(统一资源定位符)。
    通过1个URL,能找到互联网上唯一的1个资源。
    URL就是资源的地址、位置,互联网上的每个资源都有一个唯一的URL。

    URL中常见的协议

    (1)HTTP
    超文本传输协议,访问的是远程的网络资源,格式是http://
    http协议是在网络开发中最常用的协议。
    (2)file
    访问的是本地计算机上的资源,格式是file://(不用加主机地址)
    (3)mailto
    访问的是电子邮件地址,格式是mailto:
    (4)FTP
    访问的是共享主机的文件资源,格式是ftp://

    URN、URI

    URN:Uniform Resource Name,统一资源名称,指互联网上某一独一无二的资源的名称。
    URI:Uniform Resource Identifier,统一资源标志符,是标志互联网上某一资源的字符串,它包含URL和URN。所以,URN如同一个人的名称,URL代表一个人的地址。

    二、HTTP

    HTTP的全称是Hypertext Transfer Protocol,超文本传输协议。
    HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
    HTTP属于应用层面向对象协议。

    1.通信过程

    (1)请求:客户端向服务器索要数据。
    (2)响应:服务器返回客户端相应的数据。

    2.请求

    HTTP协议规定:1个完整的由客户端发给服务器的HTTP请求中包含以下内容:

    • 请求行:包含了请求方法、请求资源路径、HTTP协议版本,例如:GET /MJServer/resources/images/1.jpg HTTP/1.1
    • 请求头:包含了对客户端的环境描述、客户端请求的主机地址等信息。
      Host: 192.168.1.105:8080 // 客户端想访问的服务器主机地址
      User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9) Firefox/30.0// 客户端的类型,客户端的软件环境
      Accept: text/html, /// 客户端所能接收的数据类型
      Accept-Language: zh-cn // 客户端的语言环境
      Accept-Encoding: gzip // 客户端支持的数据压缩格式
    • 请求体:客户端发给服务器的具体数据,比如文件数据。
    3.响应

    客户端向服务器发送请求,服务器应当做出响应,即返回数据给客户端。
    HTTP协议规定:1个完整的HTTP响应中包含以下内容:

    • 状态行:包含了HTTP协议版本、状态码、状态英文名称。例如:HTTP/1.1 200 OK
    • 响应头:包含了对服务器的描述、对返回数据的描述。
      Server: Apache-Coyote/1.1 // 服务器的类型
      Content-Type: image/jpeg // 返回数据的类型
      Content-Length: 56811 // 返回数据的长度
      Date: Mon, 23 Jun 2014 12:54:52 GMT // 响应的时间
    • 实体内容:服务器返回给客户端的具体数据,比如文件数据。
    4.常见状态码
    5.发送请求的方法

    在HTTP/1.1协议中,定义了8种发送http请求的方法:GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH。最常用的是GET和POST。GET和POST的主要区别表现在数据传递上。

    GET

    在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开,比如:http://ww.test.com/login?username=123&pwd=234&type=JSON
    由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB。

    POST

    发给服务器的参数全部放在请求体中
    理论上,POST传递的数据量没有限制(具体还得看服务器的处理能力)。

    对比

    (1)如果要传递大量数据,比如文件上传,只能用POST请求
    (2)GET的安全性比POST要差些,如果包含机密\敏感信息,建议用POST
    (3)如果仅仅是索取数据(数据查询),建议使用GET
    (4)如果是增加、修改、删除数据,建议使用POST

    三、OC原生网络类

    1.NSURLConnection

    iOS9已弃用

    2.NSURLSession

    使用简单,先根据对象创建一个Task,然后执行Task即可。

    (1)NSURLSessionConfiguration

    用于配置NSURLSession工作模式以及网络设置。

    //工作模式
    //普通模式:可以使用缓存
    @property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
    //瞬时模式:不使用缓存
    @property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
    //后台模式:在后台时仍能进行下载操作,需要唯一的identifier标识
    + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
    
    //允许使用蜂窝数据
    @property BOOL allowsCellularAccess;
    
    (2)NSURLSession获取
    //共享会话,使用全局的cookie,缓存数据
    @property (class, readonly, strong) NSURLSession *sharedSession;
    //使用配置好的configuration
    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
    //与第二种类似,制定了delegate
    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
    
    (3)NSURLSessionTask

    会话任务,通过NSURLSession创建,有下面3种常用子类:

    NSURLSessionDataTask

    最普通的网络访问,多用来获取xml或者json。创建后的NSURLSessionTask需要调用resume才会执行。

    NSURLSessionDownLoadTask

    用来处理下载任务。

    NSURLSessionUploadTask

    用来处理上传任务,NSURLSessionDataTask的子类。

    (4)发送请求
        NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        request.HTTPMethod = @"POST";
        request.HTTPBody = [@"" dataUsingEncoding:NSUTF8StringEncoding];
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (error == nil) {
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
                NSLog(@"%@",dic);
            }
        }];
        [dataTask resume];
    
    (5)代理方法
    #import "DJViewController.h"
    @interface DJViewController ()<NSURLSessionDataDelegate>
    
    @end
    
    @implementation DJViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        request.HTTPMethod = @"POST";
        request.HTTPBody = [@"" dataUsingEncoding:NSUTF8StringEncoding];
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
        [dataTask resume];
        
        
    }
    
    
    //接收服务器响应的时候调用该方法
    -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
        /*
         需要使用completionHandler回调告诉系统如何处理服务器返回的数据,默认是取消
        NSURLSessionResponseCancel = 0,//取消
        NSURLSessionResponseAllow = 1,//接收服务器返回的数据
        NSURLSessionResponseBecomeDownload = 2,//变成下一个请求
        NSURLSessionResponseBecomeStream//变成一个流
        */
        completionHandler(NSURLSessionResponseAllow);
    }
    //接收到服务器返回数据会调用该方法,如果数据较大,那么该方法会调用多次
    -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
        
    }
    //当请求完成的时候会调用该方法
    -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
        
    }
    
    @end
    
    3.CFNetwork

    CFNetwork是ISO中一个比较底层的网络框架,C语言编写,可以控制一些更底层的东西,如各种常用网络协议、Socket通讯等。

    (1)CFNetwork结构
    • CFSocket
      Socket是网络通讯的底层基础,两个Socket端口可以互发数据。我们通常使用的是BSD Socket,CFSocket则是BSD Socket的抽象,基本上实现了几乎所有BSD Socket的功能,并且还融入了RunLoop。
    • CFStream
      CFStreamAPI提供了数据读写的方法,即读写流,使用它可以为内存、文件、网络(使用Socket)的数据建立stream,我们进行网络请求就是对数据的读写,CFStream提供API对两种CFType对象提供抽象:CFReadStreamCFWriteStream。它同时也是CFHTTP和CFFTP的基础。stream有一个很重要的特性就是一旦数据流被提供或者被消耗,就不能从流中重新取出。
    • CFFTP
      对用FTP协议通信的封装,能下载、上传文件和目录到FTP服务器。CFFTP建立的连接可以是同步或者异步。
    • CFHTTP
      是HTTP协议的抽象,主要对象是CFHTTPMessageRef(类似于我们通常的NSURLRequest)我们需要像构建NSURLRequest那样来构建CFHTTPMessageRef
      必要元素:
      请求方法 (类型为CFStringRef):POST、GET、DELETE等。
      请求的URL地址 (类型为CFURLRef):https://www.baidu.com
      请求的HTTP版本(类型为CFStringRef):通常使用kCFHTTPVersion1_1。
      kCFAllocatorDefault:用于创建消息引用的指定默认的系统内存分配器。
      可选参数:
      body体(类型为CFDataRef)。
      消息头部,如User-Agent等。
      #######(2)CFNetwork请求过程
    #import "DJViewController.h"
    #import <CFNetwork/CFNetwork.h>
    @interface DJViewController ()<NSURLSessionDataDelegate>
    @property(nonatomic,strong)NSMutableData *imageData;
    @end
    
    @implementation DJViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        CFStringRef urlStr = CFSTR("http://pics.sc.chainaz.com/files/pic/pic9/201605/apic20649.jpg");
        CFStringRef method = CFSTR("GET");
        CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlStr, NULL);
        CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1);
        CFRelease(url);
        CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
        CFRelease(request);
        //设置流的context,这里将self传入,用于回调
        CFStreamClientContext ctx = {0,(__bridge  void *)(self),NULL,NULL,NULL};
        //设置回调事件,用于监听网络事件
        CFOptionFlags event = kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered;
        CFReadStreamSetClient(readStream, event, myCallBack, &ctx);
        //打开输入流
        CFReadStreamOpen(readStream);
        //将流加入到runloop中
        CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
        //开启runloop
        CFRunLoopRun();
        
    }
    //回调函数
    void myCallBack(CFReadStreamRef stream,CFStreamEventType type,void *clientCallBackInfo){
        DJViewController *selfClass = (__bridge  DJViewController *)clientCallBackInfo;
        if (type == kCFStreamEventHasBytesAvailable) {
            UInt8 buff[255];
            CFIndex length = CFReadStreamRead(stream, buff, 255);
            if (!selfClass.imageData) {
                selfClass.imageData = [NSMutableData data];
            }
            [selfClass.imageData appendBytes:buff length:length];
        }
        else if (type == kCFStreamEventEndEncountered) {
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            //关闭流
            CFReadStreamClose(stream);
            //将流从runloop中移除
            CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
        }
    }
    @end
    
    4.AFNetworking
    (1)NSURLSession网络请求模块
    • AFHTTPSessionManager继承自AFURLSessionManager,post、get、上传。
    • AFURLSessionManager管理所有的请求,设置了NSURLSessionTaskDelegate, NSRULSessionDataDelegateNSURLSessionDownloadDelegate实现证书合法性校验,数据传输进度检测,数据请求成功/失败的回调。
      使用Runtime用af_suspend替换suspend, 用af_resume替换了resume 当调用者两个方法时往上层发送通知AFNetworkingTaskDidSuspendNotificationAFNetworkingTaskDidResumeNotification
      请求服务器数据、上传数据、多线程下载数据
    (2)Reachability监测网络状态模块

    AFNetworkReachabilityManager

    (3)Security安全策略模块

    AFSecurityPolicy
    iOS项目将服务器端的证书保存导入到项目中,AFN根据项目中的服务器证书来进行验证,验证服务器,保证访问服务器的安全性。
    验证证书的模式有三种:
    AFSSLPinningModeNone不验证
    AFSSLPinningModePublicKey只验证公钥
    AFSSLPinningModeCertificate验证证书的所有内容

    (4)Serialization序列化

    AFURLRequestSerialization
    AFURLResponseSerialization

    (5)UIKit UI相关的一些类目
    (6)原理概述

    AFNetworking是对NSURLSessionTask的封装。AFHTTPSessionManager继承AFURLSessionManager对网络请求进行管理,使用AFURLRequestSerialization对网络请求进行封装,使用AFURLResponseSerialization对响应体进行处理,使用AFSecurityPolicy对服务器证书进行校验。支持HTTPS协议,支持本地证书和服务器证书进行对比验证。AFN数据传递主要使用block和Notification方式。

    (7)请求过程

    1)GET/POST方法调用抽象的请求方法,指明请求参数,调用全能数据请求方法,指明数据请求方式和参数。
    2)对请求进行序列化,如果序列化失败,就执行failure block。
    3)为每一个NSURLSessionDataTask的dataTask增加代理。
    4)对每一个NSURLSessionDataTask的dataTask增加代理的具体实现,对dataTask设置请求之后的回调delegate和处理block。

    三、HTTPS

    HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。
    HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP之间)。这个系统提供了身份验证与加密通讯方法。

    1.SSL

    SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。
    SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。
    SSL协议可分为两层:
    SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
    SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

    (1)SSL单向认证具体过程

    1)客户端向服务器传送客户端SSL协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息。
    2)服务器向客户端传送SSL协议的版本号,加密算法的种类,随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。
    3)客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的CA是否可靠,发行者证书的公钥能否正确解开服务器证书的"发行者的数字签名",服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。
    4)用户端随机产生一个用于后面通讯的"对称密码",然后用服务器的公钥(服务器的公钥从步骤2中的服务器的证书中获得)对其加密,然后将加密后的"预主密码"传给服务器。
    5)如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的"预主密码"一起传给服务器。
    6)如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的CA是否可靠,发行CA 的公钥能否正确解开客户证书的发行CA的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的"预主密码 ",然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。
    7)服务器和客户端用相同的主密码即"通话密码",一个对称密钥用于SSL协议的安全数据通讯的加解密通讯。同时在SSL通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。
    8)客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤7中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。
    9)服务器向客户端发出信息,指明后面的数据通讯将使用的步骤7中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。
    10)SSL的握手部分结束,SSL安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。
    SSL单向认证只要求站点部署了ssl证书就行,任何用户都可以去访问(IP被限制除外等),只是服务端提供了身份认证。

    (2)SSL双向认证具体过程

    1)客户端发送一个连接请求给安全服务器。
    2) 服务器将自己的证书,以及同证书相关的信息发送给客户端。
    3)客户端检查服务器送过来的证书是否是由自己信赖的CA中心(如沃通CA)所签发的。如果是,就继续执行协议;如果不是,客户端就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。
    4)接着客户端比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果是一致的,客户端认可这个服务器的合法身份。
    5)服务器要求客户端发送自己的证书。收到后,服务器验证客户端的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得客户端的公钥。
    6)客户端告诉服务器自己所能够支持的通讯对称密码方案。
    7) 服务器从客户端发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户端的公钥加过密后通知浏览器。
    8)客户端针对这个密码方案,选择一个通话密钥,接着用服务器的公钥加过密后发送给服务器。
    9)服务器接收到客户端送过来的消息,用自己的私钥解密,获得通话密钥。
    10) 服务器、客户端接下来的通讯都是用对称密码方案,对称密钥是加过密的。
    双向认证则是需要服务端与客户端提供身份认证,只能是服务端允许的客户能去访问,安全性相对于要高一些。

    (3)SSL双向认证和SSL单向认证的区别

    双向认证 SSL 协议要求服务器和用户双方都有证书。单向认证 SSL 协议不需要客户拥有CA证书,具体的过程相对于上面的步骤,只需将服务器端验证客户证书的过程去掉,以及在协商对称密码方案,对称通话密钥时,服务器发送给客户的是没有加过密的(这并不影响 SSL 过程的安全性)密码方案。这样,双方具体的通讯内容,就是加过密的数据,如果有第三方攻击,获得的只是加密的数据,第三方要获得有用的信息,就需要对加密的数据进行解密,这时候的安全就依赖于密码方案的安全。而幸运的是,目前所用的密码方案,只要通讯密钥长度足够的长,就足够的安全。这也是我们强调要求使用128位加密通讯的原因。

    2. HTTPS使用NSURLSession请求
    
    #import "ViewController.h"
    
    @interface ViewController ()<NSURLSessionDataDelegate>
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        /*
        HTTPS请求的时候:
        [1] 证书是受信任的,什么都不用做
        [2] 证书是不受信任的,是自签名的
            (1) 修改配置文件,禁用ATS特性
            (2) 信任并安装(数字证书)
        */
    
        //    12306(之前不是ca认证这里仍然使用该网站举例)
            NSURL *url = [NSURL URLWithString:@"https://kyfw.12306.cn/otn/"];
    
            NSURLSession *session = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
            
            NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                   
                   NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                   
            }];
               
            [dataTask resume];
        
        
    }
    
    #pragma mark - NSURLSessionDataDelegate
    /*
    challenge:挑战,质询
    当我们发送的是一个HTTPS请求的时候就会调用该方法,需要在该方法中处理证书
    NSURLAuthenticationMethodServerTrust:服务器信任
    HTTP:80
    HTTPS:443
    */
    - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
        
        
        NSLog(@"%@",challenge.protectionSpace);
         /*
           NSURLSessionAuthChallengeUseCredential = 0, 使用证书
           NSURLSessionAuthChallengePerformDefaultHandling = 1,  忽略证书
           NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 请求被取消,证书被忽略
           NSURLSessionAuthChallengeRejectProtectionSpace = 3, 拒绝
            */
        
        //判断只有当时NSURLAuthenticationMethodServerTrust的时候才安装这个证书
           if (![challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
               return;
           }
        
        //根据服务器中的保护控件的服务器信任,来创建一个认证信息
        NSURLCredential *credential = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
        
    }
    
    @end
    
    3.HTTPS使用AFNetworking发送请求
    #import "ViewController.h"
    #import "AFNetworking.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        /**
         //证书受信任
         
        //01 创建会话管理者对象
         AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
         //修改对响应的序列化方式
         manager.responseSerializer = [AFHTTPResponseSerializer serializer];
         
         //02 发送请求
         [manager GET:@"https://www.alipay.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             
             NSLog(@"%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]);
         } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             NSLog(@"error---%@",error);
         }];
        */
        
        
        //01 创建会话管理者对象
         AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
         //修改对响应的序列化方式
         manager.responseSerializer = [AFHTTPResponseSerializer serializer];
         
         //设置AFN中的安全配置
        //01 允许接收无效的证书
         manager.securityPolicy.allowInvalidCertificates = YES;
        //02 不做域名验证
         manager.securityPolicy.validatesDomainName = NO;
         //03 修改info.plist文件ATS
         
         //02 发送请求
         [manager GET:@"https://kyfw.12306.cn/otn/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             
             NSLog(@"%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]);
         } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             NSLog(@"error---%@",error);
         }];
         
    }
    
    /**
     AFNetworking:中的类AFSecurityPolicy说明:
     
     AFSecurityPolicy,内部有三个重要的属性,如下:
    
     AFSSLPinningMode SSLPinningMode;    //该属性标明了AFSecurityPolicy是以何种方式来验证
     BOOL allowInvalidCertificates;      //是否允许不信任的证书通过验证,默认为NO
     BOOL validatesDomainName;           //是否验证主机名,默认为YES
    
     "AFSSLPinningMode"枚举类型有三个值,分别是AFSSLPinningModeNone、AFSSLPinningModePublicKey、AFSSLPinningModeCertificate。
    
     "AFSSLPinningModeNone"代表了AFSecurityPolicy不做更严格的验证,"只要是系统信任的证书"就可以通过验证,不过,它受到allowInvalidCertificates和validatesDomainName的影响;
    
     "AFSSLPinningModePublicKey"是通过"比较证书当中公钥(PublicKey)部分"来进行验证,通过SecTrustCopyPublicKey方法获取本地证书和服务器证书,然后进行比较,如果有一个相同,则通过验证,此方式主要适用于自建证书搭建的HTTPS服务器和需要较高安全要求的验证;
    
     "AFSSLPinningModeCertificate"则是直接将本地的证书设置为信任的根证书,然后来进行判断,并且比较本地证书的内容和服务器证书内容是否相同,来进行二次判断,此方式适用于较高安全要求的验证。
    
     如果HTTPS服务器满足ATS默认的条件,而且SSL证书是通过权威的CA机构认证过的,那么什么都不用做。如果上面的条件中有任何一个不成立,那么都只能修改ATS配置。
    
     
     */
    
    @end
    

    四、HTTPS和HTTP的区别

    (1)HTTPS协议需要到ca申请证书,一般免费证书很少,需要交费。
    (2)HTTP是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的SSL加密传输协议。
    (3)HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
    (4)HTTP的连接很简单;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。

    相关文章

      网友评论

        本文标题:iOS网络(二)-HTTP、HTTPS

        本文链接:https://www.haomeiwen.com/subject/qradoltx.html