专注iOS开发

[iOS]网络请求中的证书验证-NSURLSession

2016-12-07  本文已影响147人  PlutoMa

记录一下在网络请求中证书验证的基于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);
    }
}
上一篇下一篇

猜你喜欢

热点阅读