苹果在2016年的时候,给开发者传递了一个消息,就是从2017年开始,App必须启用 App Transport Security应用程序安全传输协议,提升应用安全性,即支持Https。
在 iOS 开发中,我们就需要将url改成https... , 我们常用的网络请求库有 AFNetworking 、MKNetworkKit 等。下面就说下自己的对这两个库支持https的过程吧。
第一步:先找后端拿证书
首先是找后端,后端肯定是已经支持https了的,和后端说需要一个支持https的证书,.crt 结尾的证书,后端就知道了。 拿到之后,使用终端将 .crt 证书转换成 .cer 证书,这是我们需要的。
打开终端输入:
openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
(注意:路径要正确。)
获得 .cer 证书后,拖入到项目工程中。 假设我的证书名为 AirMonitor.cer
第二步:
AFNetworking
因为我是有将请求提取封装在一个基类当中,所以,
在网络请求的基类中,添加下面这个方法:
+ (AFSecurityPolicy *)customSecurityPolicy {
// 先导入证书 证书由服务端生成,具体由服务端人员操作
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"AirMonitor" ofType:@"cer"];//证书的路径
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = [[NSSet alloc] initWithObjects:cerData, nil];
return securityPolicy;
}
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.requestSerializer.timeoutInterval = REQUEST_TIME;
// 添加证书验证
[manager setSecurityPolicy:[WBBaseHttpRequest customSecurityPolicy]];
[manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure ? failure(error) : nil;
}];
这样之后 AFNetworking 所有的https请求就会成功了。
MKNetworkKit
MKNetworkKit 的验证证书方式就会相对简单一些,验证证书方式如下:(举一个方法)
+ (void)MKuploadWithURLString:(NSString *)URLString
parameters:(id)parameters
uploadParam:(WBUploadParam *)uploadParam
success:(void (^)(id responseObject))success
failure:(void (^)(NSError *error))failure {
MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:HOST];
MKNetworkOperation *op = [engine operationWithPath:URLString params:parameters httpMethod:@"GET" ssl:YES];
[op addData:uploadParam.data forKey:uploadParam.name mimeType:uploadParam.mimeType fileName:uploadParam.filename];
// 添加验证证书
op.clientCertificate = [[NSBundle mainBundle] pathForResource:@"AirMonitor" ofType:@"cer"];;
// 当证书不合法时是否继续访问
op.shouldContinueWithInvalidCertificate = YES;
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
NSDictionary *dict = [completedOperation responseJSON];
BLOCK_SAFE_CALLS(success, dict);
} errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
BLOCK_SAFE_CALLS(failure, error);
}];
[engine enqueueOperation:op];
}
注意红字部分, 使用的是带 ssl 参数的接口,并设置为 YES,意思启用安全传输。 然后 在请求中添加证书,并且设置当证书不合法时是否继续访问。这样在 MKNetworkKit 中也能正常访问 https了。
最后,如果大家有遇到https 其它的问题,欢迎提出讨论,方便大家少入坑。。。