iOS - NSURLAuthenticationChallenge的问题 - 连接成功但无法访问服务器

时间:2012-07-24 00:39:56

标签: ios authentication webserver

我正在使用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登录页面,因为这不符合此项目的要求。

0 个答案:

没有答案