Ios 通过SSL请求web服务

Ios 通过SSL请求web服务,ios,objective-c,ios6,nsmutableurlrequest,Ios,Objective C,Ios6,Nsmutableurlrequest,我正在努力使用https请求web服务。我遇到了这样的错误: An error occured : The certificate for this server is invalid. You might be connecting to a server that is pretending to be “SERVER_ADDRESS” which could put your confidential information at risk. 我没有使用NSURLConnectionLe

我正在努力使用https请求web服务。我遇到了这样的错误:

An error occured : The certificate for this server is invalid. You might be connecting to a server that is pretending to be “SERVER_ADDRESS” which could put your confidential information at risk.
我没有使用NSURLConnectionLegate。以下是我的方法:

- (void)sendRequestWithUrl:(NSURL*)url block:(void (^)(NSDictionary *dict, NSError *error)) block{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    NSError* err = nil;
    NSHTTPURLResponse* rsp = nil;
    // Perform the request synchronously on this thread
    NSData *rspData = [NSURLConnection sendSynchronousRequest:request returningResponse:&rsp error:&err];
    if (rspData && err == nil) {
        NSDictionary *result = [NSJSONSerialization JSONObjectWithData:rspData options:NSJSONReadingMutableLeaves error:&err];
        if(result) {
            block(result, err);
        } else {
            block(nil, err);
        }
    }else{
        DLog(@"Requesting URL: %@  An error occured : %@",url,[err localizedDescription]);
        block(nil, err);
    }
}

我怎样才能解决这个问题

苹果公司有一个技术说明很好地涵盖了这一点:

“技术说明TN2232:HTTPS服务器信任评估”


对于自签名证书,这种情况经常发生。通过使用
nsurlconnectionelegate

- (BOOL)connection:(NSURLConnection *)connection
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        return YES;
    }
}

您应该在通信类中添加以下委托方法

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        if ([YOUR_HOST isEqualToString:challenge.protectionSpace.host])
        {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];           
        }
    }   
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

尝试这种委托方法为我解决了同样的问题

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

我的解决方案是创建类
AsyncURLConnection
,这段代码我在某处找到,但现在找不到。因此,我将给出代码:

AsyncURLConnection

.h

#import <Foundation/Foundation.h>

typedef void (^completeBlock_t)(NSData *data);
typedef void (^errorBlock_t)(NSError *error);

@interface AsyncURLConnection : NSObject{
    NSMutableData *data_;
    completeBlock_t completeBlock_;
    errorBlock_t errorBlock_;
}

+ (id)request:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock;
- (id)initWithRequest:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock;
+ (id)requestWithMutable:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock;
- (id)initWithMutableRequest:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock;
@end
因此,在某些控制器中,可以使用该类:

+ (void) downloadFileForURL:(NSURL *) url completionBlock:(void (^)(NSData *data, NSError *error)) block {
    NSString *requestURL = @"https://www.google.lt/restServer/Method";
    [AsyncURLConnection request:requestURL completeBlock:^(NSData *data) {
        /* success! */
        dispatch_queue_t downloadQueue = dispatch_queue_create("Download queue", NULL);
        dispatch_async(downloadQueue, ^{
            /* process downloaded data in Concurrent Queue */
            if (data != nil) {
                block(data, nil);
            }else{
                block(nil,nil);
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                /* update UI on Main Thread */
            });
        });
    } errorBlock:^(NSError *error) {
        /* error! */
        block(nil,error);
    }];
}
希望这段代码能对一些人有所帮助


谢谢大家的回答

在我看来,您在使用自签名证书时遇到了问题。。对的我建议您更改为诸如或之类的lib,这使此类问题更容易处理。检查:另外,可能重复:我不想使用其他库。另外,在给定的其他问题的解决方案是去擦亮在这种情况下,这可能会有帮助:而且,这可能会有帮助(1年前的职位):。你能找到的东西真是太神奇了,只需使用谷歌;)如何将此代码调整为我的代码?我知道如何使用NSURLConnectionLegate,但是如何使用blocks来执行它为什么不想使用NSURLConnectionLegate?有什么东西可以破坏你的代码吗?我想更新我当前的代码,因为在其他方面,我需要做很多的更改,因为现在所有的事情都是分块完成的。我也喜欢用这种方法编写代码,看看AFN网络。它使用成功和失败块以及NSURLConnectionLegate。如果您不能直接使用该框架,您可能会在那里找到帮助您解决问题的代码。
+ (void) downloadFileForURL:(NSURL *) url completionBlock:(void (^)(NSData *data, NSError *error)) block {
    NSString *requestURL = @"https://www.google.lt/restServer/Method";
    [AsyncURLConnection request:requestURL completeBlock:^(NSData *data) {
        /* success! */
        dispatch_queue_t downloadQueue = dispatch_queue_create("Download queue", NULL);
        dispatch_async(downloadQueue, ^{
            /* process downloaded data in Concurrent Queue */
            if (data != nil) {
                block(data, nil);
            }else{
                block(nil,nil);
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                /* update UI on Main Thread */
            });
        });
    } errorBlock:^(NSError *error) {
        /* error! */
        block(nil,error);
    }];
}