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, попробуйте зарегистрировать строку и удалить новые строки, иначе заголовок не будет установлен.

Другие вопросы по тегам