美文网首页专注iOS开发
[iOS]网络请求中的证书验证-NSURLSession

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

作者: PlutoMa | 来源:发表于2016-12-07 10:59 被阅读147次

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

    相关文章

      网友评论

        本文标题:[iOS]网络请求中的证书验证-NSURLSession

        本文链接:https://www.haomeiwen.com/subject/pcydmttx.html