带有基本身份validation挑战的NSURLSession

我search了所有可用的解决scheme在stackoverflow。 仍然与此混淆。
请指出我是否有任何错误。 我得到401错误。

NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://qa.api.xxxxxx.com/v0/jobs/93033"]]; NSString *authStr = @"xxxxxxxx:xxxxxxxxxxx"; NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding]; NSString *authValue = [NSString stringWithFormat:@"Basic %@",[authData base64EncodedStringWithOptions:0]]; [request setValue:authValue forHTTPHeaderField:@"Authorization"]; request.HTTPMethod = @"GET"; [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request addValue:@"application/json" forHTTPHeaderField:@"Accept"]; //create the task NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if (httpResponse.statusCode == 200) { NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"%@",json); dispatch_async(dispatch_get_main_queue(), ^{ }); } else { // failure: do something else on failure NSLog(@"httpResponse code: %@", [NSString stringWithFormat:@"%ld", (unsigned long)httpResponse.statusCode]); NSLog(@"httpResponse head: %@", httpResponse.allHeaderFields); return; } }]; [task resume]; 

也许你的请求被redirect到了一些新的请求,而这个请求是NSURLSession自动生成的,没有授权头。

您可以使用Wireshark来跟踪您的请求发生。

如果您的请求被redirect,您可以使用以下方法确保新请求使用身份validation信息发送:

1.使用委托方法处理authentication

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { if (challenge.previousFailureCount > 1) { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); }else { NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user" password:@"pswd" persistence:NSURLCredentialPersistenceForSession]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } } 

应该是处理authentication的最佳方式。

2.使用委托方法将authentication标题添加到新请求

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler { NSMutableURLRequest *newRequest = request.mutableCopy; // Add authentication header here. completionHandler(newRequest); } 

请求redirect时再次添加validation标头。

3.将身份validation标题设置为NSURLSession的附加标题

 NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; config.HTTPAdditionalHeaders = @{@"Authorization":@"Basic xxxxxxxxxxxxxxxxxx"}; NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; 

确保NSURLSession使用该身份validation头创build新的请求。

也许你的输出authValue包含新行后,你做base64,尝试loggingstring和删除新行,否则标题将不会设置。

使用didReceiveAuthenticationChallenge方法,是在iOS中使用基本授权的正确方法。

请求:

  NSURL *URL = [NSURL URLWithString:@"http://qa.api.freshersworld.com/v0/jobs/93033"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; 

代表:

 - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { if ([challenge previousFailureCount] == 0) { NSLog(@"received and handle authentication challenge"); NSURLCredential *newCredential = [NSURLCredential credentialWithUser:@"xxxx" password:@"xxxx" persistence:NSURLCredentialPersistenceForSession]; [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge]; } else { NSLog(@"previous authentication failure"); } } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"%@", response); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSString* responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", responseString); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"%@", error); }