记录一下在网络请求中证书验证的基于NSURLSession的实现
一.开始一个请求
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.data = [NSMutableData data];
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://XXXXXXXXX"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:240];
[request setHTTPMethod:@"POST"];
[request setHTTPShouldHandleCookies:YES];
NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData *postData = [@"XXX=XXX&XXX=XXX" dataUsingEncoding:gbkEncoding];
[request setHTTPBody:postData];
[[self.session dataTaskWithRequest:request] resume];
}
二.实现NSURLConnection验证的回调方法
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
// 如果是请求证书信任,我们再来处理,其他的不需要处理
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
SecTrustRef trust = challenge.protectionSpace.serverTrust;
//获取本地证书
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"XXX" ofType:@"cer"]];
SecTrustResultType result;
SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(data));
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)@[CFBridgingRelease(certificate)]);
NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == errSecSuccess &&
(result == kSecTrustResultProceed ||
result == kSecTrustResultUnspecified)) {
//验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接
// 调用block
completionHandler(NSURLSessionAuthChallengeUseCredential,cred);
} else {
//验证失败,取消这次验证流程
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, cred);
}
}
}
三.接收数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.data appendData:data];
}
四.处理数据
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString *retStr = [[NSString alloc] initWithData:self.data encoding:enc];
NSLog(@"retString:%@",retStr);
NSData* newData=[retStr dataUsingEncoding:NSUTF8StringEncoding];
id responseObject = [NSJSONSerialization JSONObjectWithData:newData options:NSJSONReadingMutableLeaves error:&error];
if (error) {
NSLog(@"error:%@",error);
} else {
NSLog(@"%@", responseObject);
}
}