Это более быстрый / лучший способ форсировать аутентификацию с помощью NSURLConnection, а не метод делегата? - PullRequest
1 голос
/ 30 сентября 2011

Если я знаю, что аутентификация требуется для моего серверного API, лучше / лучше напрямую принудительно выполнить аутентификацию с использованием заголовка http, а не ждать, пока сервер вернет ответ 401, а затем ответить на него в подключении метода делегата NSURLConnection: didReceiveAuthenticationChallenge:

1 Ответ

4 голосов
/ 10 октября 2011

"Более простой способ" предоставить учетные данные для аутентификации на сервере - это использовать метод делегата NSURLConnection

didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

, где вы можете предоставить учетные данные, подобные этому

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    if ([challenge previousFailureCount] == 0) {

        NSURLCredential *newCredential;
        newCredential = [NSURLCredential credentialWithUser:userName password:password persistence:NSURLCredentialPersistenceNone];
        [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
    } else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

То, что произойдет, это то, что вы сначала вызовете сервер с вашим запросом GET / POST, и если сервер требует аутентификации, и учетные данные не были предоставлены в заголовке HTTTP, он (надеюсь) ответит ответом 401. Вышеуказанный метод будет запускать и предоставлять предоставленные учетные данные.

Но если вы знаете, что вашему серверу всегда требуется аутентификация, этот дополнительный раунд взаимодействия клиент / сервер неэффективен, и вам будет лучше предоставить свои учетные данные прямо в заголовке HTTP.

Метод предоставления учетных данных внутри заголовка HTTP прост, если не считать того, что в iOS нет метода кодирования в BASE64.

NSMutableURLRequest *aRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30];

// first create a plaintext string in the format username:password  
NSMutableString *loginString = (NSMutableString *)[@"" stringByAppendingFormat:@"%@:%@", userName, password];  

// encode loginString to Base64
// the Base64 class is not provided and you will have to write it!
NSString *encodedLoginData = [Base64 encode:[loginString dataUsingEncoding:NSUTF8StringEncoding]];  

// prepare the header value   
NSString *authHeader = [@"Basic " stringByAppendingFormat:@"%@", encodedLoginData];  

// add the authentication credential into the HTTP header
[request addValue:authHeader forHTTPHeaderField:@"Authorization"];  

// provide additional HTTP header properties (optional)     
[aRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[aRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[aRequest setHTTPMethod:@"GET"];

// and finally create your connection for above request
NSURLConnection *aConnection = [[NSURLConnection alloc] initWithRequest:aRequest delegate:self];

// don't forget to release the request and nsurlconnection when appropriate...
...