iOS开发使用https,java http请求速度慢变慢是因为什么

iOS9后https不能请求问题解决的办法之一
在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES
按照上面提到的方式添加信息,正确的修改会看到下图这个样子,注意类型NSAppTransportSecurity为Dictionary,NSAllowsArbitraryLoads为Boolean,复制粘贴的时候,不要多了空格,segment
fault 页面上直接复制,经常会多一个出空格!
注意?,单元测试下面也有一个Info.plist,修改那个文件是没有作用的!
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!iOS开发:对于AFNetworking HTTP转HTTPS请求证书问题
转载至:http://www.jianshu.com/p/551fa7482def
公司之前的请求都是HTTP的,现在要把HTTP改成HTTPS,如果我们只是单单的把http改成https,在进行网络请求的时候,会报下面的一大堆错误,大概意思也就是说证书无效,影响请求的安全性:
Domain=NSURLErrorDomain Code=-1202 "此服务器的证书无效。您可能正在连接到一个伪装成“m.dks.com”的服务器,这会威胁到您的机密信息的安全。" UserInfo=0x1741abb40 {NSURLErrorFailingURLPeerTrustErrorKey=&SecTrustRef: 0x1740cdd60&, NSLocalizedRecoverySuggestion=您仍要连接此服务器吗?, _kCFStreamErrorCodeKey=-9813, NSUnderlyingError=0x
"未能完成操作。(“kCFErrorDomainCFNetwork”错误 -1202。)", NSLocalizedDescription=此服务器的证书无效。您可能正在连接到一个伪装成“m.dks.com”的服务器,这会威胁到您的机密信息的安全。, NSErrorFailingURLKey=,
NSErrorFailingURLStringKey=, _kCFStreamErrorDomainKey=3}
我们要做的就是,从后台那里拿到一个.crt后缀的证书文件,把这个文件变成.cer后缀的文件,我此处使用的是命令行;当然你也可以使用Mac上面的钥匙串去访问,让后从政府颁发机构导出.cer的文件;打开你的终端,写下面的命令:
openssl x509 -in 后台给的.crt -out 想要的名字.cer -outform der
然后把生成的:想要的名字.cer文件导入到工程中,在自己封装AFNetworking的类中,写如下代码:
+ (AFSecurityPolicy *)customSecurityPolicy
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"Admin" ofType:@"cer"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
securityPolicy.allowInvalidCertificates = YES;
securityPolicy.validatesDomainName = NO;
NSSet *set = [[NSSet alloc] initWithObjects:certData, nil];
securityPolicy.pinnedCertificates =
return securityP
然后在封装的get请求或者是是post请求的地方,调用上面的这段代码:
+ (void)postWithURLString:(NSString *)urlString
parameters:(id)parameters
success:(SuccessBlock)successBlock
failure:(FailureBlock)failureBlock
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.requestSerializer.timeoutInterval = outT
[manager setSecurityPolicy:[SYNetworkingManager customSecurityPolicy]];
[manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id
_Nullable responseObject) {
if (successBlock) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
successBlock(dic);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failureBlock) {
failureBlock(error);
NSLog(@"网络异常 - T_T%@", error);
当我们的工程中有SDWebimage这个第三放库的时候,加载HTTPS的图片时,在iOS8上面没有问题,但是在iOS9上面,控制台就会报这样的错误:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
大概意思也是说网络请求证书的问题,不过我还没有解决这个问题,在网上找了好多,没有找到一个好的方法,如果有哪位朋友遇到这样的问题了,还希望可以在此处给解答一下,千恩万谢!!!
如果想要了解对AFNetworking的封装,请猛戳下面的链接:
文/First灬DKS(简书作者)
原文链接:http://www.jianshu.com/p/551fa7482def
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!原文 http://www.cnblogs.com/rayshen/p/3822960.html
一、非多线程HTTP请求如果不使用多线程,IOS的HTTP访问请求,以登录的模式为例,是这样://此为不正确的代码//成功进行登录验证后进入到下一ViewController-(void)presentToNextview{& //到下一界面}//登录验证-(void)loginCheck{& //包含POST或GET请求来完成数据的验证,验证成功就跳转到下一界面}-(void)showindicator{& //显示登录时转圈圈的菊花}//登录按钮的点击事件-(IBAction)loginBTN:(id)sender{& //执行的函数有:& [self showindicator];& [self loginCheck];}这样写代码的结果就是indicator菊花一到logincheck函数执行就会卡主,直到POST或GET请求完成才&卡到下一界面&。网络不好的情况下就是类似死机状态。二、多线程的实现。1.子线程的创建:两种方法第一种: [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];第二种:NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];[thread start];差异:第一种直接方便,第二种在启动前可以对其的stack等参数配置,更具灵活性。2.在子线程中召唤主线程做事:[self performSelectorOnMainThread:@selector(函数名) withObject:nil waitUntilDone:YES];//如果waitUntilDone参数为YES,那么当前线程会被阻拦,直到selector运行完。3.代码简单示例一:登录//此为多线程实现登录放UI卡死的代码//成功进行登录验证后进入到下一ViewController-(void)presentToNextview{& //到下一界面}//登录验证-(void)loginCheck{& //包含POST或GET请求来完成数据的验证,验证成功就跳转到下一界面&& if(账号密码匹配){&&& //召唤主线程跳转到下一界面&&& [self performSelectorOnMainThread:@selector(presentToNextview) withObject:nil waitUntilDone:YES];&& }}-(void)showindicator{& //显示登录时转圈圈的菊花}//登录按钮的点击事件-(IBAction)loginBTN:(id)sender{& //执行的函数有:& [self showindicator];& //开辟新的线程,执行需要联网耗时的函数loginCheck& [NSThread detachNewThreadSelector:@selector(loginCheck) toTarget:self withObject:nil];}4.代码示例二:显示一张网上的图片,源代码:DownloadViewController.h#import &UIKit/UIKit.h&#import "FileConnection.h"@interface DownloadViewController : UIViewController@endDownloadViewController.m#import "DownloadViewController.h"#define kURL @"http://b.hiphotos.baidu.com/image/pic/item/32fa828ba61ea8d37ccb6e0e950a304e241f58ca.jpg"@interface DownloadViewController ()@property UIImageView *imageV@endUIActivityIndicatorView* activityIndicatorV@implementation DownloadViewController-(void)downloadImage:(NSString *) url{& NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];& UIImage *image = [[UIImage alloc]initWithData:data];& if(image == nil){&&& NSLog(@"没有图片");& }else{&&& NSLog(@"刷新图片");&&& [& activityIndicatorView stopAnimating ];//停止&&& //通知主线程做事&&& [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];&&& //如果waitUntilDone参数为YES,那么当前线程会被阻拦,直到selector运行完。& }}-(void)updateUI:(UIImage*) image{& self.imageView.image =& //sleep(5);}-(void)showindicatior{& activityIndicatorView = [ [ UIActivityIndicatorView& alloc ] initWithFrame:CGRectMake(250,30,30.0,30.0)];& activityIndicatorView.activityIndicatorViewStyle= UIActivityIndicatorViewStyleG& [self.view addSubview:activityIndicatorView];& [activityIndicatorView startAnimating];//启动}- (void)viewDidLoad{& [super viewDidLoad];& self.imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 60, 300, 220)];& & [self.view addSubview:self.imageView];& & //显示菊花& [self showindicatior];& & //开辟一个新的线程 2种方法& [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];& //NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];& //[thread start];}- (void)didReceiveMemoryWarning{& [super didReceiveMemoryWarning];& // Dispose of any resources that can be recreated.}@end
阅读(...) 评论() &iOS中http转https,及https请求抓包
iOS9推出的时候,苹果希望大家使用https协议,来提高数据传输之间的安全性。下面我就从最简单的代码介绍,如何在工程中设置,来支持https的请求。
一、证书准备篇
1.证书转换
在服务器人员,给你发送的crt证书后,进到证书路径,执行下面语句
// openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
这样你就可以得到cer类型的证书了。双击,导入电脑。2.证书放入工程
1、可以直接把转换好的cer文件拖动到工程中。
2、可以在钥匙串内,找到你导入的证书,单击右键,导出项目,就可以导出.cer文件的证书了
二、代码修改篇
先在info.plist中,增加如下图的配置
文本内容如下:
&NSAppTransportSecurity&
&NSAllowsArbitraryLoads&
1.使用系统类发送网络请求篇
1.1 NSURLConnection设置支持https。
在2015年iOS9的更新中,NSURLConnection 被废弃 由 NSURLSession 取代,所以本身是不建议大家继续用这个类做网络请求的(同样也有AFNetWorking 2.x版本),但是考虑到一些旧程序,也不能说改就改,说替换就替换的,所以还是需要普及一下,如果用到了NSURLConnection你需要怎么做。
代码如下:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:credntial forAuthenticationChallenge:challenge];
你只需要简单的,添加上如上的代理方法,就可以在不影响你原有请求的基础上,增加了https请求的支持了。
1.2 NSURLSession设置支持https。
现在推荐使用的就是NSURLSession来处理相关的网络请求了,如果使用系统自带的类,可以参考如下代码:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credntial);
NSLog(@"protectionSpace = %@",challenge.protectionSpace);
2.使用AFNetWorking发送网络请求篇
AFNetworking是一个讨人喜欢的网络库,适用于iOS以及Mac OS X. 它构建于在NSURLConnection, NSOperation, 以及其他熟悉的Foundation技术之上. 它拥有良好的架构,丰富的api,以及模块化构建方式,使得使用起来非常轻松.。
2.1 AFNetWorking 2.x版本
考虑到这个版本,我们还可以使用AFHTTPRequestOperationManager这个类来处理网络请求。所以我们要做的就是给这个类,设置一些参数,让它可以支持https的请求,代码如下:
支持https(校验证书,不可以抓包):
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
mgr.securityPolicy.SSLPinningMode = AFSSLPinningModeC
NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"cer"];
NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
mgr.securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:cerData, nil];
mgr.securityPolicy.allowInvalidCertificates = YES;
[mgr.securityPolicy setValidatesDomainName:NO];
支持https(不校验证书,可以抓包查看):
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
mgr.securityPolicy.SSLPinningMode = AFSSLPinningModeC
mgr.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
mgr.securityPolicy.allowInvalidCertificates = YES;
[mgr.securityPolicy setValidatesDomainName:NO];
2.2 AFNetWorking 3.x版本
在Xcode7.0之后,苹果废弃了NSURLConnection方法,数据请求使用NSURLSession,作为网络请求类第三方库使用量最大的AFN也及时的更新的新的版本——AFN 3.0版本。新的版本的里废弃了基于NSURLConnection封装的AFHTTPRequestOperationManager,转而使用基于NSURLSession封装的AFHTTPSessionManager了。
支持https(校验证书,不可以抓包):
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy.SSLPinningMode = AFSSLPinningModeC
NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"cer"];
NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:cerData, nil]];
mgr.securityPolicy.allowInvalidCertificates = YES;
[mgr.securityPolicy setValidatesDomainName:NO];
支持https(不校验证书,可以抓包查看):
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
manager.securityPolicy.allowInvalidCertificates = YES;
[manager.securityPolicy setValidatesDomainName:NO];
三、使用Charles抓包https
3.1 软件下载篇
1 工欲善其事必先利其器,需要工具的同学可以在这里,密码: gknp!
下载到V3.9.3版本的Charles软件下载软件后,打开软件,然后command + q退出。
之后将破解文件,放到下面路径
应用程序-&Charles-&显示包内容-&Contents-&Resources里面,替换即可。
3.2 程序配置篇
1.进入Charles的配置界面
2.按图上操作
这样设置之后理论上就可以抓所有网址443端口的https请求了。但是还没完。我们还需要安装一个证书。如下图:
3.进入钥匙串,找到这个证书
单击右键,显示简介。如下图设置为始终信任
以上电脑端的准备就差不多了。
我们还需要在iPhone手机上,下载一下描述文件。
具体操作,大家就要点开这个网址,手机下载。注意:手机点开这个网址
如下图操作
QQ@2x.png-341.8kB
经过上面些步骤,我们已经把相应的软件以及证书都布置好了。之后,只需要在手机连接wifi后,设置手机代理。服务器填写电脑ip地址,端口号为8888.
现在你就可以感受用Charles抓https的请求啦。注意代码要写上面的可以抓包的代码,也就是无证书校验的。如果是有证书校验的,大家就不要妄想抓数据啦。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求
& & 本篇博客主要讨论如何在客户端与服务端之间进行HTTPS网络传输,为了深入理解网络传输的基础原理,更加灵活的校验证书,博客的前半部分也将介绍一些HTTPS网络传输原理。当然,文章中有不正和疏漏之处,还望朋友不吝指正,感谢!
二、HTTP与HTTPS
& & & 我们都知道,HTTP是一种常用的网络传输协议,它是基于TCP的一种应用层协议,应用层是什么样的一个概念,通过下面这张示意图可以很好的理解:
HTTP协议的网络传输十分常见,例如网易的主页http://www.163.com/。HTTP类型的网络传输使用十分方便,但是其在安全性上却有很大问题,列举如下:
1.HTTP协议在传输数据时是明文的,任何人通过一个简单的抓包工具,就可以截获到所有传输数据。
2.HTTP协议在传输数据时无法保证数据的完整,在截获到明文数据后,很容易就可以将其篡改,这也是一些网页总是被植入恶意广告的原因。
3.HTTP协议在传输数据时无法保证真实性,这也是最恐怖的一点。误入了域名欺骗的钓鱼网站,极容易对用户带来财产损失。
基于上面3点安全性的考虑,一种更加安全的网络传输协议势必要推行,那就是HTTPS。
&&&&& 要理解HTTPS协议,首先需要明白什么是SSL/TLS。SSL全称“Secure Sockets Layer”,意思为安全套接层。其实由网景公司为了解决HTTP传输协议在安全方面的缺陷而设计的。后来被标准化,更名为TLS,全称“Transport Layer Security”,意思为传输层安全协议。
&&&&& & 那么现在就好理解了,其实HTTPS就是将HTTP协议与TLS协议组合起来,在不改变HTTP协议原设计的基础上,为其添加安全性校验并对传输的数据进行加密。那么TLS究竟在网络传输的那一层进行了处理了,下图可以很好的表示:
&&&&& 通过前面所介绍,我们知道HTTPS主要是为了解决3个问题:数据加密、数据完整、数据真实。那么下一步就是如何解决这些问题,数据加密在发送数据前依赖SSL层对数据进行加密,数据完整与真实性则要靠另一种关键技术:数字证书。
& & & 通过一个小例子可以很容易的理解证书的作用,这个例子的来源是&编程随想&的作者,我这里暂且借用一下:A公司的a到B公司办事,为了证明a确实是A公司的职员而不是商业间谍,A公司会为a提供一个带有公章的证明,当B公司看到这个证明时,就可以信任办事员a。对比网络传输,这个证明就是证书,证书可以保证这个网站的真实性。我们继续往后分析,当B公司与越来越多的公司进行商业合作时,就又有新的问题出现了,比如C公司的c来B公司办事,就需要拿C公司带公章的证明,D公司的d来B公司办事就需要拿D公司带公章的证明...这样一来,B公司要存放好多公司的公章和证明的模板,才能够完成校验。这样未免也太麻烦了,对应到网络传输中,客户端就是B公司,各个网站都有自己的证书文件,这样客户端需要安装信任大量的证书,为了解决这样的问题,就有了第三方CA机构。第三方CA机构是由大家公认信任的机构,例如R公司为第三方信任机构,其业务是为其他公司提供公章证明,这样一来,B公司只要保有这个R公司的公章证明副本,其他A,C,D公司的办事员也只需要从R公司申请到一个公章证明就可以到B公司来交流业务了。
& & CA的全称是“Certificate Authority”,意为证书授权中心。大部分CA机构颁发的证书都是需要付费的,CA机构颁发的证书一般都是根证书,根证书也比较容易理解,首先证书是有链式信任关系的,例如Y证书是由CA机构颁发的根证书,由这个Y证书还可以创建出许多子证书,子证书可以继续创建子证书,只要根证书是受信任的,其下所有的子证书都是受信任的,如下图:
& & 我们可以打开开源中国博客的主页:。在Chrome浏览器地址栏左边可以查看证书信息,如下:
点击证书信息,可以看到完整的证书链,如下图:
从图中可以看到,根证书是由CA机构VerSign公司颁发的。此处还可以看到当前证书是否有效以及过期时间,如果证书无效则说明此网页信息有可能被篡改过,用户在访问时就要小心了。
& & 除了CA机构可以签发证书外,个人其实也是可以创建证书的,当然个人创建的证书也是不被信任的,我们姑且把这类证书叫做自签名证书,如果用自签名证书搭建了HTTPS的服务,则客户端需要安装对应的证书信任,才可以进行此服务的访问。后面我们会进一步讨论自签名证书的使用。
四、搭建一个本地的HTTPS服务
& & 使用Node.js可以快速的搭建前端服务,我们这里使借助Express框架来搭建本地的HTTPS服务,用于测试我们后边将要进行HTTPS通讯。Express搭建搭建项目模板的过程在以前的一篇博客中有详细的介绍,这里就不再重复了,地址如下:
使用Express搭建前端项目:。
& & 根据前面所述,搭建HTTPS服务需要有证书凭证,两种证书我们可以选择,一种是CA机构签发的证书,还有一种是我们自己制作的自签名证书,在Mac电脑上打开钥匙串访问应用,打开其中的证书助理,如下图所示:
选择其中的为您自己创建证书选项,如下图:
在之后的界面中,输入证书的名称,选择证书类型,如下图所示:
上面,我把证书的名字创建成了珲少,身份类型选择的是自签名的根证书,证书类型选择SSL服务器,之后点击创建即可完成证书的创建。
& & 创建完成后,在钥匙串访问的登录证书中,可以看到已经有了珲少这个自签名的证书,如下图:
在证书上点击右键,选择导出选项,名字我将其取名为huishao,文件类型要选择.p12,如下图所示:
点击存储后,需要设置一个访问密码,这个密码将来将用于从.p12文件中获取证书和密钥,如下图所示:
之后,系统有可能会让你再次输入一个密码,将入下图所示,注意,这里需要输入的是系统的登录密码:
完成上面操作后,我们已经将一个.p12文件导出到了桌面。那么这个.p12文件到底是个什么东西呢,它和证书之间又有什么关系呢,其实.p12文件一个复合文件,其中包装了私钥与证书信息,使用OpenSSL工具可以将其中的信息进行提取,搭建一个HTTPS的服务器需要两个文件,分别问证书文件和私钥文件,下面我们来从.p12文件中提取这些需要的文件。
& & &打开终端,cd到huishao.p12文件所在的目录下,使用如下命令可以将.p12文件中的私钥分解出来:
openssl pkcs12 -in huishao.p12 -nocerts -out privateKey.pem -nodes
之间会要求输入导出.p12文件时所设置的密码。
使用如下命令将.p12文件中的证书分解出来:
openssl pkcs12 -in huishao.p12 -nokeys -out cert.pem -nodes
之间也会要求输入导出.p12文件时所设置的密码。完成上面两部操作后,可以看到当前文件夹下多了两个文件,分别为cert.pem与privateKey.pem,他们分别是证书文件与密钥文件,将他们拷贝到Express项目的bin文件夹下,使得Express项目的结构看起来如下图所示:
下面我们来配置Express项目。
&&&&& 在生成好的Express项目中的www文件的末尾添加如下代码:
var fs = require('fs');
var https = require('https');
var privatekey = fs.readFileSync('./privateKey.pem', 'utf8');
var certificate = fs.readFileSync('./cert.pem', 'utf8');
var options={key:privatekey, cert:certificate};
var serverHttps = https.createServer(options, app);
serverHttps.listen(8080,function () {
console.log('Https server listening on port ' + 8080);
用终端在bin文件夹下运行 node www,效果如下:
在浏览器打开:https://localhost:8080/users,如果服务器搭建成功,Chrome中会出现如下效果:
点击高级,点击其中的继续访问,可以正常获取到服务器返回的数据。到此,我们的HTTPS服务就搭建成功了。
五、iOS开发中通过配置info.plist文件来允许HTTP协议类型的通讯
& & & 前面扯了太多,终于提到重点部分了。Apple在iOS9中就已经漏出一些强制HTTPS通讯的端倪,只是给了开发者一些过渡,在iOS10及以后的审核机制中,Apple对于强制HTTPS的推动将会越来越强,如何让自己的应用程序尽快的适配HTTPS相关的标准,是iOS开发者必须面对的任务。
&&&&& 通过前面的分析我们了解,CA机构签发的证书是被默认信任的,这就是说,如果你的公司比较有钱,愿意花钱从CA机构申请一个付费的证书,那么很幸运,你的iOS工程是不需要做任何修改的,这些CA机构签发的证书是默认受信任的,因此你可以直接在程序中进行HTTPS类型的请求,所需要修改的只是将请求url改成https开头。但是另一种情况,无论出于什么原因,你的后台服务用的是自签名的证书,就想我们上面搭建的HTTPS服务一样,如果在不做任何处理的情况下在项目中访问这样的服务,就会出现问题了,原因是我们自己创建的自签名证书是不受信任的,系统默认拒绝了请求,示例如下:
-(void)normalHttps{
NSURLRequest * req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://localhost:8080/users"]];
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
[[session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@,%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
}] resume];
运行工程后可以看到,并没有获取到相关数据,Xcode提示为:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
好了,那么我们先不管HTTPS的问题,如果我们直接对HTTP协议的服务进行请求,会不会有问题呢,将代码修改如下:
-(void)normalHttps{
NSURLRequest * req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:3000/users"]];
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
[[session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@,%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
}] resume];
需要注意:Express在进行项目模板的创建时,会默认帮我们绑定一个3000端口的HTTP服务。
运行工程后,可以发现HTTP协议的请求也无法访问,报错如下:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
其意思大致是说应用程序传输安全要求强制使用HTTPS类型的服务,但是开发者可以通过配置info.plsit文件来回避这一政策。这就是我们这节的重点,通过文件配置的方式来跳过应用安全传输协议。
& & 在iOS9之后,开发者可以在Info.plist文件中添加如下键:NSAppTransportSecurity。这个键用来配置APP传输安全的相关策略,是字典类型,其中可以设置的键有五个,如下:
NSAllowsArbitraryLoads:布尔值,默认为NO,设置为YES则代表除了NSExceptionDomains中设置的域名外,其他所有请求的协议类型都不受限制,也就是说可以支持HTTP类型的请求,这个键的作用域是全局的,App内所有的请求都受影响,但是如果开发者设置为了YES,在提交审核时需要说明原因。
NSAllowsArbitraryLoadsForMedia:布尔值,默认为NO,设置为YES的话,则应用程序内所有的媒体数据的加载将不受协议类型的限制,同样如果开发者设置为了YES,则在提交审核时需要说明原因。
NSAllowsArbitraryLoadsInWebContent:布尔值,默认为NO。如果设置为YES,则应用程序内所有WebView的请求加载不受协议类型的限制,开发者设置为了YES,则在提交审核时需要说明原因。
NSAllowsLocalNetworking:布尔值,默认为NO,如果设置为YES,则在加载本地资源时不受安全传输协议的限制。
NSExceptionDomains:字典,其主要对某些特殊域名做限制。其中结构可以表示如下:
NSAppTransportSecurity : Dictionary {
NSAllowsArbitraryLoads : Boolean
NSAllowsArbitraryLoadsForMedia : Boolean
NSAllowsArbitraryLoadsInWebContent : Boolean
NSAllowsLocalNetworking : Boolean
//对某些域名做特殊限制
NSExceptionDomains : Dictionary {
&domain-name-string& : Dictionary {
NSIncludesSubdomains : Boolean
NSExceptionAllowsInsecureHTTPLoads : Boolean
NSExceptionMinimumTLSVersion : String
NSExceptionRequiresForwardSecrecy : Boolean
// Default value is YES
NSRequiresCertificateTransparency : Boolean
NSIncludesSubdomains:布尔值,这个键的作用是设置此域名下的所有子域名是否采用和父域名相同的配置。
NSExceptionAllowsInsecureHTTPLoads:布尔值,设置是否允许此域名使用自签名的证书进行请求,默认为NO,如果设置为YES,则在提交时需要说明原因。
NSExceptionMinimumTLSVersion:设置所使用的TLS版本。
NSExceptionRequiresForwardSecret:设置为NO,则不允许向前加密方式。
NSRequiresCertificateTransparency:如果设置为YES,则服务端的证书要有有效的透明时间戳。
六、iOS中使用自签名的证书进行HTTPS请求校验
& & 通过Info.plist文件我们是可以绕过安全传输协议的,但是不幸的是,从文档上看,无论开发者通过哪种方式来绕过安全传输协议,Apple都要求开发者在提审时提供合适的理由,这就是说:如果你使用了HTTP协议的请求,没有充足理由的话,你的App有很大的可能被审核拒绝。因此,更加保险的一种方式是将所有的服务都换成HTTPS协议的,如果有CA证书,当然完事大吉,如果没有,我们也可以通过验证自签名证书的方式来适配HTTPS协议。
& & 在进行HTTPS请求时,服务端会先将证书文件返回给客户端,如果客户端的证书信任列表中包含这个证书,则此请求可以正常进行,如果没有,则请求会被拒绝。因此,在iOS中适配自签名证书的HTTPS请求实际上就是将这个自签名的证书安装进客户端的信任列表。iOS中需要使用的证书是der格式的,可以使用如下命令将pem格式的证书转换成der格式的证书:
openssl x509 -inform PEM -in cert.pem -outform DER -out cert.der
将生成的cert文件添加进工程中,修改请求如下:
-(void)normalHttps{
NSURLRequest * req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://localhost:8080/users"]];
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask * task = [session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@,%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
[task resume];
除此之外,需要实现一个SURLSessionDelegate的协议方法如下:
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
NSLog(@"证书认证");
//先判断证书是否有效
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
//证书验证请求
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA)
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"der"];//自签名证书
NSData* caCert = [NSData dataWithContentsOfFile:cerPath];
//可以添加多张证书
NSArray *caArray = @[caCert];
//验证规则
NSMutableArray *policies = [NSMutableArray array];
[policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
NSMutableArray *pinnedCertificates = [NSMutableArray array];
//进行自签名证书的添加
for (NSData *certificateData in caArray) {
[pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
SecTrustResultType result = -1;
//通过本地导入的证书来验证服务器的证书是否可信
SecTrustEvaluate(serverTrust, &result);
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
return [[challenge sender] useCredential: credential
forAuthenticationChallenge: challenge];
如上修改后,再次运行工程,可以看到已经成功请求到了HTTPS自签名证书服务提供的数据:
介于篇幅过长,关于NSURLAuthenticationChallenge相关类的更多探讨和常用网络库AFNetworking中HTTPS的适配,下篇博客会继续介绍。
专注技术,热爱生活,交流技术,也做朋友。
——珲少 QQ群:
& 著作权归作者所有
人打赏支持
是开源中国针对行业特定技术问题发起的专家问答。
领取条件:受邀参与高手问答的技术专家可以领取
码字总数 437123
评论删除后,数据将无法恢复
iOS精选源码 快速创建menuItem控件 YHPhotoBrowser 优化的网络图片浏览 cocoaAsynSocket demo (包含客户端和服务端) SwipeMenuViewController现在支持iPhoneX和Swift4。 仿微信的提醒对话框 ...
sunnyaigd ?
  昨天傍晚盘古实验室负责任的披露了针对 iOS 应用的 ZipperDown 漏洞,并提供了检索、查询受影响应用的平台: zipperdown.com。基于目前公开的信息,该漏洞的影响面比较大,15000 多个应用...
FreeBuf ? 05/16 ?
iOS精选源码 TYCyclePagerView iOS上的一个无限循环轮播图组件(http://www.code4app.com/thread-.html) iOS高仿微信完整项目源码(http://www.code4app.com/thread-.html)......
sunnyaigd ? 06/12 ?
一、MDM相关知识: MDM (Mobile Device Management ),即移动设备管理。在21世纪的今天,数据是企业宝贵的资产,安全问题更是重中之重,在移动互联网时代,员工个人的设备接入企业网络并查...
移动互联百科 ?
目录 前言 API Demo 前言 本文主要是把NSURLSession以及NSURLSessionTask相关的代理方法全部整理了一下。 旨在大体了解在一个iOS网络请求中、一个任务究竟经理了什么。 而我们、又能做些什么...
kirito_song ? 05/10 ?
iOS精选源码 一款优秀的 聆听夜空FM 源码(http://www.code4app.com/thread-.html) zhPopupController 简单快捷弹出自定义视图(http://www.code4app.com/thread-.html) WHS......
sunnyaigd ? 06/04 ?
最近一周看到很多很好用的的轮子,忍不住推荐给大家。此外,本期 fir.im Weekly 还精选了一些实用的 iOS , Android , UI 动画的干货文章。让我们一起来看下: Hacking with Swift 由@稀土圈...
风起云飞fir_im ?
原文:https://www.toutiao.com/a8990600/?ttfrom=weixin&utmcampaign=clientshare&timestamp=&app=newsarticle&utmsource=weixin&iid=&utmmedium=toutiao......
鸿蒙无上至尊 ? 06/22 ?
目录 第一部分 iOS6新内容 第二部分 从每天工具中获取更多(介绍日常使用控件和框架的潜力) 第三部分 完成任务的正确工具(介绍不是那么常用的控件和框架) 第四部分 发挥到极限(深入理解i...
云飞扬v5 ?
AFNetworking是一个为 iOS 和 Mac OSX 制作的令人愉快的网络库,它建立在URL 装载系统框架的顶层,内置在Cocoa里,扩展了强有力的高级网络抽象。它的模块架构被良好的设计,拥有丰富的功能,...
lewis-180 ?
没有更多内容
加载失败,请刷新页面
每次查点东西csdn就一大堆你抄我我抄你,互相抄,抄也就罢了,全部复制粘贴,没有一点自己的思想? 我**妈的
开飞色 ? 36分钟前 ?
wmzsonic ? 今天 ?
yizhichao ? 今天 ?
1 git clone 1.1 克隆远程库 # https协议git clone https://github.com/yysue/test.git# ssh协议 推荐这种git clone :yysue/test.git 克隆时,指定远程主机名 git clone ......
yysue ? 今天 ?
一、队列 1.队列的定义 队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表; 与栈相反,队列是一种先进先出(First In First Out,FIFO)的线性表; 与栈相同的是,队列...
aibinxiao ? 今天 ?
其实简单的来说,大数据就是通过分析和挖掘全量的非抽样的数据辅助决策。 大数据可以实现的应用可以概括为两个方向,一个是精准化定制,第二个是预测。比如像通过搜索引擎搜索同样的内容,每...
董黎明 ? 今天 ?
import java.awt.Cimport java.awt.GridLimport java.awt.event.ActionEimport java.awt.event.ActionLimport javax.swing.JBimport......
游人未归 ? 今天 ?
介绍如何使用Struts2的struts2-json-plugin.jar插件返回JSON数据。 一、其中主要步骤有: 1.将struts2-json-plugin.jar插件拷贝到项目的"/WEB-INF/lib"文件夹下; 2.编写Action类文件; 3.在...
文文1 ? 今天 ?
1.下载软件 1.1 VMware 1.2 下载centos7 下载地址:https://www.centos.org/download/ 2. 安装vmware 第一步: 第二步: 第三步: 第四步: 第五步: 第六步: 第七步:破解VMware 点击破解软...
Lucky_Me ? 今天 ?
对于运行在后台的Docker容器,我们运维人员时常是有登陆进去的需求。登陆Docker容器的方式: 1)使用ssh登陆容器。这种方法需要在容器中启动sshd,存在开销和攻击面增大的问题。同时也违反了...
bengozhong ? 今天 ?
没有更多内容
加载失败,请刷新页面
文章删除后无法恢复,确定取消删除此文章吗?
亲,自荐的博客将通过私信方式通知管理员,优秀的博客文章审核通过后将在博客推荐列表中显示
确定推荐此文章吗?
确定推荐此博主吗?
聚合全网技术文章,根据你的阅读喜好进行个性推荐
指定官方社区
深圳市奥思网络科技有限公司版权所有

我要回帖

更多关于 tomcat请求慢的原因 的文章

 

随机推荐