2

パスワードを検証し、無効なパスワードで401エラーを返すサーバーと、失敗した試行回数を指定するjson本体と通信しています。その数は、検証に失敗するたびにサーバーによって増分されます。

私が直面している問題は、NSURLConnectionが401応答を取得すると、次のデリゲートメソッドを含む認証メカニズムを開始することです。

connection:canAuthenticateAgainstProtectionSpace:

connection:didReceiveAuthenticationChallenge:

canAuthenticateメソッドでNOを返すと、新しい同一の要求が行われます。これにより、サーバーは失敗した試行を2回目にインクリメントし(これは明らかに望ましくありません)、401応答を受け取ります(connection:didReceiveResponse :)

canAuthenticateメソッドでYESを返すと、 didReceiveAuthenticationChallengeメソッドが呼び出されます。2番目のリクエストを停止したい場合は、[challenge.sender cancelAuthenticationChallenge:challenge]を呼び出すことができます。しかし、そうすると、401応答は返されませんが、エラーが発生します。

最初の401応答をキャプチャする方法が見つかりませんでした。それを行う方法はありますか?

4

2 に答える 2

2

1) クライアント証明書のない単純なバニラ SSL の場合、これら 2 つのメソッドを実装する必要はありません。

2) それでもやりたい場合は、[challenge failureResponse] オブジェクトの HTTP 応答コードを確認する必要があります。

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSURLCredential *urlCredential = [challenge proposedCredential];
    NSURLResponse *response = [challenge failureResponse];
    int httpStatusCode = -1;
    if(response != nil) {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        httpStatusCode = [httpResponse statusCode];
    }    
    if(urlCredential != nil || httpStatusCode == 401) {
        //wrong username or more precisely password, call this to create 401 error
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
    else {
        //go ahead, load SSL client certificate or do other things to proceed
    }    
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{       

 return YES;
}
于 2013-08-27T23:05:47.113 に答える
0

他のすべてが失敗した場合は、これを試してください: AFNetworkingと呼ばれる素晴らしいライブラリが利用可能で、実装が非常に簡単です。

これは、クラス間のデータ通信を非常に単純化する (デリゲートを排除する) ブロックを使用し、非同期です。

使用例は次のとおりです。

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:"www.yourwebsite.com/api"]];

NSDictionary *params = @{
    @"position": [NSString stringWithFormat:@"%g", position]
};

[client postPath:@"/api" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

}];

それと同じくらい簡単です!結果は、HTTP Post または Get メソッドを呼び出すクラス内で直接利用できます。

画像と JSON のリクエスト、JSON の逆シリアル化、進行状況のコールバックを伴うファイルのダウンロードなども含まれます。

于 2012-12-19T04:27:49.387 に答える