一、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
CFStream
API提供了数据读写的方法,即读写流,使用它可以为内存、文件、网络(使用Socket)的数据建立stream,我们进行网络请求就是对数据的读写,CFStream
提供API对两种CFType对象提供抽象:CFReadStream
和CFWriteStream
。它同时也是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
,NSRULSessionDataDelegate
,NSURLSessionDownloadDelegate
实现证书合法性校验,数据传输进度检测,数据请求成功/失败的回调。
使用Runtime用af_suspend替换suspend, 用af_resume替换了resume 当调用者两个方法时往上层发送通知AFNetworkingTaskDidSuspendNotification
、AFNetworkingTaskDidResumeNotification
请求服务器数据、上传数据、多线程下载数据
(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协议安全。
网友评论