NSURLSession с вызовом базовой аутентификации
Я искал все доступные решения в stackru. Все еще путают с этим.
Пожалуйста, укажите мне, если я делаю какую-либо ошибку. Я получаю 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];
3 ответа
Возможно, ваш запрос перенаправлен куда-то еще с новым запросом, который автоматически генерируется NSURLSession без заголовка авторизации.
Вы можете использовать Wireshark для отслеживания вашего запроса.
Если ваш запрос перенаправлен, вы можете использовать следующие методы, чтобы убедиться, что новый запрос отправляется с информацией аутентификации:
1. Используйте метод делегата для обработки аутентификации
- (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);
}
}
Должен быть лучший способ справиться с аутентификациями.
2. Используйте метод делегата для добавления заголовка аутентификации в новый запрос
- (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);
}
Снова добавьте заголовок аутентификации, когда ваш запрос будет перенаправлен.
3. Установите заголовок аутентификации в качестве дополнительного заголовка в NSURLSession
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.HTTPAdditionalHeaders = @{@"Authorization":@"Basic xxxxxxxxxxxxxxxxxx"};
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
Убедитесь, что NSURLSession создает новый запрос с этим заголовком аутентификации.
Использование подхода 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);
}
Возможно, ваш вывод authValue содержит новые строки после того, как вы выполните base64, попробуйте зарегистрировать строку и удалить новые строки, иначе заголовок не будет установлен.