NSURLSession With Basic Authentication Challenge

柔情痞子 提交于 2019-12-12 09:27:39

问题


I searched all the solution avaliable in stackoverflow. Still confused with this.
Please point me if i am doing any mistake. I am getting 401 error.

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];

回答1:


Perhaps your request is redirected to some where else with a new request which is auto-generated by NSURLSession without authorization header.

You could use Wireshark to track your request exactly happened.

If your request is redirected, you can use the following methods to make sure the new request is sending with authentication information:

1. Use Delegate Method to Handle 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);
    }
}

Should be best way to handle authentications.

2. Use Delegate Method to Add Authentication Header to New Request

- (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);
}

Add authentication header again when your request gets redirect.

3. Set Authentication Header As Additional Header To NSURLSession

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

Make sure NSURLSession creates new request with that authentication header.




回答2:


Perhaps your output of authValue contains new lines after you do base64, try to log the string and remove new lines, otherwise the header won't set.




回答3:


Using didReceiveAuthenticationChallenge approach, is the correct way to work with basic authorization in iOS.

Request:

 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];

Delegate:

- (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);
}


来源:https://stackoverflow.com/questions/39314034/nsurlsession-with-basic-authentication-challenge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!