我一直在尝试解决这个问题一段时间,但没有成功。诸如此处的这个问题或关于使用苹果和其他博客的身份验证的问题提供了一些启示,但并非全部。
我想解决的基本问题如下:
我通过使用 NSURLConnection 其代表和 NSURLCredential 与 NSURLProtectionSpace 和 NSURLCredentialStorage 成功地对我的服务器进行身份验证。但是,即使我将 NSURLCredential 的持久性设置为 NSURLCredentialPersistencePermanent,在第一次提供我的凭据之后,我还是会从服务器随机获取身份验证挑战(401,然后是 200)——难道不是这种情况,因为 NSURLCredentialPersistencePermanent 会永久持续吗?随机的事情是没有意义的。
有时它可以工作,随后对服务器的调用以 200 返回正常。然后它又没有,并且返回 200 的 401。Mike Abdullah 在这里很好地描述了这个过程。所以我的第一个猜测是,返回 401 身份验证并获得 200 的过程是标准程序,无法消除。但是有时我可以消除 401。所以我似乎错过了一些东西。
我发送的请求是一些 GET 和两个 POST。问题是一个 POST 正在上传大量数据。当得到 401 时,数据仍然会在验证后再次上传到 nirvana 中。
我的后备解决方案是防止在收到 401 时发送数据。我现在正在处理这个问题,这似乎很棘手,因为有时 401 没有像前面提到的那样返回。
如果这以任何方式无法理解,我会添加任何信息。我的猜测是要么我以错误的方式使用整个 NSURLCredential 东西,要么首先获得 401 然后 200 进行身份验证的方式是要走的路,因此无法消除。
我的代码摘录如下:
loginCredential = [NSURLCredential credentialWithUser:@"foo"
password:@"bar"
persistence:NSURLCredentialPersistencePermanent];
NSURLProtectionSpace *loginProtectionSpace = [[NSURLProtectionSpace alloc] initWithHost:@"foo.com"
port:8000
protocol:@"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodBasic];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:loginCredential
forProtectionSpace:loginProtectionSpace];
[loginProtectionSpace release];
loginCommunicator = [[LearnCommunicator alloc] initWithMethod:@"login-foo"
credential:loginCredential];
使用此设置,NSURLConnection 的代表都可以正确调用
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
{
NSLog(@"connectionShouldUseCredentialStorage user: %@",[userCredential user]);
return YES;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
NSLog(@"canAuthenticateAgainstProtectionSpaceuser: %@",[userCredential user]);
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"didReceiveAuthenticationChallenge previousFailureCount: %i",[challenge previousFailureCount]);
if ([challenge previousFailureCount] == 0)
{
NSLog(@"Challenging...");
[[challenge sender] useCredential:userCredential forAuthenticationChallenge:challenge];
}
else
{
NSLog(@"Username and password are incorrect");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
任何输入表示赞赏!谢谢
编辑更新 01这似乎是一个已知问题,它已作为错误报告提交 - 很久以前 - 但尚未解决。NSURLConnection 似乎不支持“Expect: 100-continue”标头,老实说,这是一个主要的失望。我一直在这个问题上工作几个小时,只是为了发现现在我必须重做所有事情。有关详细信息,请参阅错误报告:http: //openradar.appspot.com/5188833
编辑更新 02我目前针对此问题的解决方法是在使用电影数据进行大量 HTTP POST 之前简单地进行身份验证。由于我还必须上传一些较小的 XML 文件,因此我将使用它的事先身份验证来上传电影。这对我来说仍然很难看,但我必须让事情继续下去......关于这个主题的任何输入/知道如何仍然受到赞赏。