问题
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