【问题标题】:NSURLConnection retry on 401 statusNSURLConnection 重试 401 状态
【发布时间】:2012-12-19 02:02:18
【问题描述】:

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

我面临的问题是,当 NSURLConnection 收到 401 响应时,它会启动涉及这些委托方法的身份验证机制:

连接:canAuthenticateAgainstProtectionSpace:

连接:didReceiveAuthenticationChallenge:

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

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

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

【问题讨论】:

  • 马里亚诺,你有没有想过如何解决这个问题?我现在面临同样的问题:(

标签: ios nsurlconnection nsurlconnectiondelegate


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果一切都失败了,试试这个:一个很棒的库,叫做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 在调用 HTTP Post 或 Get 方法的类中直接可用。

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

    【讨论】:

    • 是的,AFNetworking 是一个很棒的库,但是我有很多围绕 NSURLConnection 构建的代码。
    • 您不需要替换旧代码。我知道当我第一次在工作场所开始使用它时,我们的整个应用程序都是围绕 NSURLConnection 设计的。但我们已经慢慢过渡到现在一切都使用 AFNetworking 的地步。
    猜你喜欢
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2011-10-18
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多