2

NSURLAuthenticationChallenge を使用して、アプリから Web サーバーにログインしています。サーバーが必要とするのは、ユーザー名とパスワードだけです。何が起こっているかは次のとおりです。

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

もう 1 つの問題: アプリの実行中にメッセージ リクエストをサーバーに送信するまでに長い時間待機すると、サーバーはユーザーがログアウトしたと見なし、上記と同じ動作を示します。

編集: この 2 番目の問題は未解決のままです。追加情報 - マジック タイム ラグ数は 10 秒のようです。つまり、サーバーが認証してから 10 秒以上待ってからファイルを要求すると、サーバーは要求を認識せず、認証されていない要求の場合と同様に、代わりに Web ログイン ページを送信します。 .

何が起こっているのか分かりますか?いいえ、このプロジェクトの要件を満たしていないため、アプリ内に Web サーバーのログイン ページをロードすることはできません。

4

0 に答える 0