NSUrlSession NSUrlConnection https连接时证书无效的解决办法
来源:互联网 发布:js正则表达式大全 编辑:程序博客网 时间:2024/06/05 07:39
The certificate for this server is invalid
最近公司项目需要从网络端获取部分数据,原来的接口是http的,iOS9引入的ATS机制:
所有的http请求都改成了https,采用TLS 1.2协议,目的是增强数据安全。如果不更新的话,暂时可以在Info.plist中声明,使用不安全的网络请求。首先我们在info.plist中加入以下参数:
<key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <true/></dict>
然后使用下面代码可以获取到数据:
- (NSDictionary *)postToserver:(NSURL *)address paramers:(NSDictionary *)param { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:address]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil]; [request setHTTPBody:data]; NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; __block NSDictionary *tempResult = nil; dispatch_semaphore_t sem = dispatch_semaphore_create(0); NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error == nil) { NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; tempResult = result; } dispatch_semaphore_signal(sem); }]; [task resume]; dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); return tempResult;}
这样就项目就支持http了,但是切换到HTTPS又有问题了。
切换到HTTPS
App Transport Security要求TLS 1.2而且它要求站点使用支持forward secrecy协议的密码。证书也要求是符合ATS规格的。因此慎重检查与你的应用交互的服务器是不是符合ATS的要求非常重要。但是有的时候小公司证书(你懂的~~~),所以我们需要在API检测证书是否有效的时候过滤掉我们的server。如果不这样操作,会出现以下错误:
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “s3.amazonaws.com” which could put your confidential information at risk." UserInfo=0x20007030 {NSErrorFailingURLStringKey=https://s3.amazonaws.com/.../test.jpeg, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLKey=https://s3.amazonaws.com/.../test.jpeg, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “s3.amazonaws.com” which could put your confidential information at risk., NSUnderlyingError=0x20014d40 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “s3.amazonaws.com” which could put your confidential information at risk.", NSURLErrorFailingURLPeerTrustErrorKey=}
解决方法
1: 使用NSURLConnection
如果你使用的是NSURLConnection,需要实现NSURLConnectionDelegate方法:
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] && [challenge.protectionSpace.host hasSuffix:@"example.com"]) { // 不管证书是否有效都使用 [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; } else { [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; }}
2: 使用NSURLSession
如果使用的是NSURLSession进行网络链接,同样需要实现NSURLSessionDelegate方法:
#pragma mark -session delegate-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] && [challenge.protectionSpace.host hasSuffix:@"example.com"]) { credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; if (credential) { disposition = NSURLSessionAuthChallengeUseCredential; } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } if (completionHandler) { completionHandler(disposition, credential); }}
OK,解决问题。
注意
代码里面[challenge.protectionSpace.host hasSuffix:@”example.com”]这句判断是根据实际情况来使用,如果你想过滤掉所有的,去掉这段代码即可。
1 0
- NSUrlSession NSUrlConnection https连接时证书无效的解决办法
- iOS9中关于 NSURLSession/NSURLConnection HTTP load failed 的解决办法
- iOS开发之NSURLSession/NSURLConnection HTTP load failed 的解决办法
- 服务器证书无效的解决办法
- NSURLSession和NSURLConnection 的区别
- NSURLSession 和 NSURLConnection的区别
- NSURLSession与NSURLConnection的前仆后继
- NSURLSession/NSURLConnection HTTP load failed解决办法
- iOS里加载https请求报错说服务器证书无效的解决办法
- iOS客户端如何适配HTTPS(NSURLConnection/AFN/NSURLSession)
- NSURLConnection,NSURLSession断点续传的实现以及对比
- ios证书无效解决办法
- iOS Https 服务器证书无效
- NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824) 报错解决办法
- 用charles拦截android设备https,证书无效的解决方法
- java连接https时禁用证书验证.
- httpClient 连接 https + 证书连接
- 微信小程序免费https证书报错https证书无效
- dbcp连接池
- java读写Excel(JXL)
- 【高斯消元】[CTSC2001 D2]GPA排名系统
- 使用highchart.js
- 8168开机自动挂载nfs
- NSUrlSession NSUrlConnection https连接时证书无效的解决办法
- iOS添加左右导航按钮
- 网络爬虫介绍(待完善)
- 不读完你不会成功
- java 反编译
- 【cocos2dx】 图片格式的区别 png jpg pvr
- ubuntu 14.04 no valid active connections found
- MySQL中KEY与INDEX的区别
- Vijos 1035 贪婪的送礼者