本文介绍了NSURLConnection重试401状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与验证密码并在无效密码上返回401错误的服务器通信,以及指定失败尝试次数的json正文.服务器在每次验证失败时都会递增该数字.

I'm communicating with a server that validates a password and returns a 401 error on invalid password, together with a json body specifying the number of failed attempts. That number is incremented by the server on each failed validation.

我面临的问题是,当NSURLConnection得到401响应时,它将启动涉及以下委托方法的身份验证机制:

The problem I'm facing is that when NSURLConnection gets a 401 response, it kicks an authentication mechanism that involves these delegate methods:

连接:didReceiveAuthentication挑战:

如果我在 canAuthenticate 方法中返回NO,则将发出一个新的相同请求.这将导致服务器第二次增加失败的尝试次数(这显然是不希望的),并且我将收到401响应( connection:didReceiveResponse:)

If I return NO in the canAuthenticate method, a new identical request will be made. This will result in the server incrementing the failed attempts a second time (which is obviously not desired) and I'll get a 401 response (connection:didReceiveResponse:)

如果我在 canAuthenticate 方法中返回YES,则将调用 didReceiveAuthenticationChallenge 方法.如果我想停止第二个请求,可以致电 [challenge.sender cancelAuthenticationChallenge:challenge] .但是,如果这样做,我将不会收到401响应,而是一个错误.

If I return YES in the canAuthenticate method, then the didReceiveAuthenticationChallenge method is called. If I want to stop the second request, I can call [challenge.sender cancelAuthenticationChallenge:challenge]. But if I do that, I won't get a 401 response, but an error.

我找不到捕获第一个401响应的方法.有什么办法吗?

I've found no way to capture the first 401 response. Is there any way to do that?

推荐答案

1)对于没有客户端证书的普通SSL,您无需实现这两种方法

1) For plain vanilla SSL without client certificate you don't need to implement these 2 methods

2)如果仍然愿意,则应在[challenge failureResponse]对象中检查HTTP响应代码:

2) If you still want to, you should check for the HTTP response code in the [challenge failureResponse] object:

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

这篇关于NSURLConnection重试401状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 21:27