iOS NSURLSession Https请求

xiaoxiao2021-02-28  120

玩了半年的Android和Java后端,最近又回来搞iOS了。 做开发本着能用最新就用最新的原则,所以战略放弃了NSURLConnection,改用NSURLSession。 而且苹果倡导使用https,并且这也是未来的趋势。所以就直接上了。 我们平时在访问https的网页时会出现证书过期啊、不受信任等问题,弹出一个对话框选择是否信任证书这样的情况。For example,12306某些页面打开因为是https,所以可能出现对话框说证书不信任。而GitHub虽然也是https,但是不会出现这样的问题。 那么我们在开发过程中,如果后端使用了私有的证书,也会出现这样的问题吧,如果不信任的话,不管是调用接口还是打开网页,都会失败。 那么如何去信任证书呢?

//2程序自动安装证书的方式 NSURLSession *sesson = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

首先我们要设置NSURLSession,添加代理方法。

NSURLSession * sesson = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

注意:不能使用上面的这个方法,这样是进不去代理方法的!

然后在代理方法中实现对证书的操作 方法一:这是在开发者足够信任后端的安全的情况下做的,比如调个接口,这样做的结果就是忽略证书的验证,直接信任。

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){//服务器信任证书 NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];//服务器信任证书 if(completionHandler) completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } }

方法二:可以把证书加到工程中,然后https访问时在代理方法中进行证书的验证

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ SecTrustRef servertrust = challenge.protectionSpace.serverTrust; SecCertificateRef certi= SecTrustGetCertificateAtIndex(servertrust, 0); NSData *certidata = CFBridgingRelease(CFBridgingRetain(CFBridgingRelease(SecCertificateCopyData(certi)))); NSString *path = [[NSBundle mainBundle] pathForResource:@"https" ofType:@"cer"]; NSData *localCertiData = [NSData dataWithContentsOfFile:path]; if ([certidata isEqualToData:localCertiData]) { NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:servertrust]; [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); NSLog(@"服务端证书认证通过"); }else { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); NSLog(@"服务端认证失败"); } }

OK,这样就可以访问https的接口、网页了。


- (void)getWithUrlString:(NSString *)f_str_url NSString:(NSString *)f_aTC_String success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{ NSMutableString * t_aTC_mutableUrl = [[NSMutableString alloc] initWithString:f_str_url]; [t_aTC_mutableUrl appendString:f_aTC_String]; NSLog(@"url %@",t_aTC_mutableUrl); NSURL * t_aTC_URL =[NSURL URLWithString:[t_aTC_mutableUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]]; NSURLRequest * t_aTC_urlRequest = [NSURLRequest requestWithURL:t_aTC_URL]; //2程序自动安装证书的方式 NSURLSession *sesson = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]]; NSURLSessionDataTask * t_aTC_dataTask = [sesson dataTaskWithRequest:t_aTC_urlRequest completionHandler:^(NSData * _Nullable t_aTC_data, NSURLResponse * _Nullable t_aTC_response, NSError * _Nullable t_aTC_error) { if (t_aTC_error) { failureBlock(t_aTC_error); } else { NSString * t_str_result = [[NSString alloc] initWithData:t_aTC_data encoding:NSUTF8StringEncoding]; successBlock(t_str_result); } }]; [t_aTC_dataTask resume]; } - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ /*方法一*/ if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){//服务器信任证书 NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];//服务器信任证书 if(completionHandler) completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } /*方法二*/ SecTrustRef servertrust = challenge.protectionSpace.serverTrust; SecCertificateRef certi= SecTrustGetCertificateAtIndex(servertrust, 0); NSData *certidata = CFBridgingRelease(CFBridgingRetain(CFBridgingRelease(SecCertificateCopyData(certi)))); NSString *path = [[NSBundle mainBundle] pathForResource:@"https" ofType:@"cer"]; NSData *localCertiData = [NSData dataWithContentsOfFile:path]; if ([certidata isEqualToData:localCertiData]) { NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:servertrust]; [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); NSLog(@"服务端证书认证通过"); }else { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); NSLog(@"服务端认证失败"); } }
转载请注明原文地址: https://www.6miu.com/read-22479.html

最新回复(0)