使用 NSURLConnection 强制进行身份验证比使用委托方法更快/更好吗?

发布于 2024-12-07 12:19:59 字数 157 浏览 0 评论 0原文

如果我知道我的服务器 API 需要身份验证,那么直接使用 http 标头强制进行身份验证,而不是等待服务器返回 401 响应,然后在 NSURLConnection 委托方法 connection:didReceiveAuthenticationChallenge: 内对其进行响应,是否更快/更好?

If I know that authentication is required for my server API, is it faster/better to directly force authentication using http header instead of waiting for the server to return 401 response and then respond to it inside NSURLConnection delegate method connection:didReceiveAuthenticationChallenge:?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瑾夏年华 2024-12-14 12:19:59

向服务器提供身份验证凭据的“更简单的方法”是使用 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 请求调用服务器,并且如果服务器需要身份验证和凭据HTTP 标头中未提供,它(希望)会以 401 响应进行响应。上述方法将触发并提供提供的凭据。

但是,如果您知道您的服务器始终需要身份验证,那么进行这一轮额外的客户端/服务器通信效率并不高,您最好直接在 HTTP 标头内提供您的凭据。

除了 iOS 没有提供编码为 BASE64 的方法之外,在 HTTP 标头内提供凭据的方法很简单。

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...

The "easier way" to provide authentication credentials to a server is to use NSURLConnection delegate method

didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

where you can provide credentials similar to this

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

What will happen is that you first call server with your GET/POST request and if the server requires authentication, and credentials were not provided inside HTTTP header, it will (hopefully) respond with 401 response. The above method will trigger and provide supplied credentials.

But if you know that your server will always require authentication, it is not efficient to make this extra round of client/server communication and you will be better off to provide your credentials straight away inside the HTTP header.

The method of providing credentials inside HTTP header is simple apart from the fact that iOS doesn't come with a method to encode to 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...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文