NSURLConnection重试401状态



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

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

连接:canAuthenticateAgainstProtectionSpace:

连接:didReceiveAuthenticationChallenge:

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

如果我在canAuthenticate方法中返回YES,则调用didReceiveAuthenticationChallengechallenge.sender cancelAuthenticationChallenge:challenge]。但如果我这样做,我不会得到401的回复,而是一个错误。

我找不到捕捉第一个401响应的方法。有办法做到这一点吗?

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

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

如果其他一切都失败了,请尝试:一个很棒的库,称为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) {
}];

就这么简单!Result直接在调用HTTPPost或Get方法的类中可用。

它甚至包括图像和JSON请求、JSON反序列化、带进度回调的文件下载等等。

最新更新