2

我正在尝试使用自签名证书连接到 API 进行测试。

  -(NSData*)getDataFromPostRequestWithHeaders:(NSDictionary*)headers      withPostData:(NSData*)postData fromURL:(NSString*)urlString
    {
    __block NSData* responseData;

    NSLog(@"URL is %@", urlString);
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:10.0];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postData];
    [request setAllHTTPHeaderFields:headers];

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
   // [config setHTTPAdditionalHeaders:headers];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
    NSLog(@"%@", @"NSURLSession started successfully");
    // I.e. no I do not need to have a queue of sessions running in parallel currently.
   NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                            {
                                                NSLog(@"%@", @"completionHandler called successfully");
                                                    if (error) {
                                                        NSLog(@"Error whilst executing post request: %@", error);
                                                    } else {
                                                        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                        NSLog(@"HTTP response from this request is %@", httpResponse);
                                                        responseData = data;
                                                    }
                                                }];
    [dataTask resume];

    return responseData;
}

这是我的 didReceiveChallenge() 方法:

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
    NSLog(@"%@", @"didReceiveChallenge method of NSURLSessionDelegate called successfully");
   if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        if ([challenge.protectionSpace.host isEqualToString:@"https://dongu.ravenlabs.co.uk"])
        {
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential); // I.e. if it is this domain, then yes we can trust it.
        }
    }
}

第一个在登录方法中调用,如下所示:

-(NSString*)loginUserAndRetrieveSessionID:(NSString*)userName withPassword:(NSString*)password
{
    __block NSDictionary *responseDict;
   NSDictionary *loginHeaders = @{ @"content-type": @"application/json",
                               @"accept": @"application/json",
                               @"cache-control": @"no-cache",
                               };
    NSDictionary *parameters = @{ @"login": userName,
                                  @"password": password };

    NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
    NSString *urlString = [DONGU_API_BASE_URL stringByAppendingString:@"/session/"];
    NSData *responseData = [self getDataFromPostRequestWithHeaders:loginHeaders withPostData:postData fromURL:urlString];
    if (responseData)
    {
    responseDict = [self getDictionaryFromResponseData:responseData];
    }
    NSLog(@"%@", @"End of login method reached.");
    return [responseDict objectForKey:@"session-token"];

}

每当调用 didReceiveChallenge 时,应用程序都会完全冻结。有没有解决的办法?我试过使用 GCD 来调用登录方法,但没有任何乐趣。有没有办法解决?

4

1 回答 1

0

每次调用该方法时,您必须调用提供的完成处理程序,否则连接将不会取得进一步进展。如果您不知道如何处理特定挑战,请使用...PerformDefaultHandling.

此外,请注意,您禁用证书验证的方式非常非常不安全。至少,您应该将提供的公钥与存储在您的应用程序中某处的已知有效公钥进行比较,并且只有当它匹配时,您才应该告诉操作系统使用该凭据。否则,您将面临此代码意外出现在您的运输应用程序中的风险,并失去 TLS 的所有好处。

于 2016-11-01T21:12:51.493 回答