我正在使用NSURLAuthenticationChallenge通过我的应用登录网络服务器。所有服务器要求都是用户名和密码。以下是发生的事情:
(1)使用包含HTML标题中的User-Agent字符串的POST消息Ping服务器
(2)服务器通过 didReceiveAuthenticationChallenge 委托方法检测到的身份验证质询进行响应
(3)使用用户名和密码发送质询回复进行回复:
NSURLCredential *cred = [[NSURLCredential alloc] initWithUser:unameTextField.text
password:pswdTextField.text
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
(4)如果用户名/密码正确,则调用委托方法 connectionDidFinishLoading ,检测到服务器接受质询响应。用户现在已登录,可以从服务器发送/接收消息。 (如果用户名/密码不正确,则会调用委托方法 didFailWithError 并向用户显示警报。)
这就是出错的地方:我第一次打开Xcode项目并运行应用程序并尝试使用正确的用户名/密码登录时,步骤3和4之间的时间间隔为10-15秒。然后即使在调用 connectionDidFinishLoading 之后,当我向请求文件的服务器发送消息时,它通过向我发送HTML登录页面来响应,这是未经身份验证的请求的默认行为...所以看起来好像我我毕竟没有登录。
如果我停止然后再次运行应用程序没有延迟,一切正常。
编辑:我通过在每次登录尝试之前清除URLCache,所有cookie和所有凭据来解决上述问题。这3种方法的代码如下:
- (void)clearCookiesForURL
{
NSURL *loginUrl = [NSURL URLWithString:@"https://www.MYURL.com"];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookiesForURL:loginUrl];
for (NSHTTPCookie *cookie in cookies)
{
[cookieStorage deleteCookie:cookie];
}
}
- (void)eraseCredentials
{
NSString *urlString = @"www.MYURL.com";
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];
if ([allCredentials count] > 0)
{
for (NSURLProtectionSpace *protectionSpace in allCredentials)
{
if ([[protectionSpace host] isEqualToString:urlString])
{
NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
for (NSString *credentialKey in credentials)
{
[credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
}
}
}
}
}
- (void)eraseURLCache
{
NSURL *loginUrl = [NSURL URLWithString:@"https://www.MYURL.com"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:loginUrl];
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:urlRequest];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
}
另一个问题:如果我在应用程序运行时向服务器发送消息请求之间等待很长时间,服务器认为我已经注销并表现出与上述相同的行为。
编辑:第二个问题仍未解决。附加信息 - 看起来魔术时间滞后数是10秒。换句话说,如果我在服务器验证了我从服务器请求文件后等待超过10秒,它就无法识别我的请求并向我发送Web登录页面,就像它对未经身份验证的请求所做的那样
知道发生了什么事吗?不,我不能简单地在我的应用程序中加载webserver登录页面,因为这不符合此项目的要求。