2013-02-15 146 views
8

我很努力地使用https请求网络服务。我得到这种错误:通过SSL请求网络服务

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. 

我没有使用NSUrlConnectionDelegate。这是我的方法:

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

我怎么能解决这个问题?

+1

对我来说,你遇到了自签证书的问题..正确吗? 我建议你改成一个库,如[AFNetworking](https://github.com/AFNetworking/AFNetworking/blob/master/README.md)或[MKNetworking](https://github.com/MugunthKumar/MKNetworkKit /blob/master/README.mdown),这使得这些问题更容易处理。检查:http://stackoverflow.com/questions/13077753/need-to-view-website-with-a-self-signed-certificate-and-http-authentication – 2013-02-15 12:36:32

+1

此外,可能重复:http:// stackoverflow。 com/questions/933331 /如何使用nsurlconnection-to-connect-with-ssl-for-an-untrusted-cert – 2013-02-15 12:37:55

+1

我不想使用其他库。另外在给定的其他问题解决方案 – Streetboy 2013-02-16 07:50:40

回答

1

您应该将下面的委托方法添加到您的通信类。

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

这始终是自签名证书发生。通过使用NSURLConnectionDelegate

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

这段代码如何调整到我的?我知道如何使用NSURLConnectionDelegate,但是如何使用块 – Streetboy 2013-02-19 09:55:28

+0

做到这一点,为什么你不想使用NSURLConnectionDelegate?有什么可以破坏你的代码吗? – 2013-02-19 10:12:12

+0

我想更新我当前的代码,因为在其他方面,我需要做很多改变,因为现在一切都是按块完成的。另外我喜欢用这种方法编写代码 – Streetboy 2013-02-19 11:11:06

0

尝试使用这种委托方法解决了同样的问题。

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

那么我的解决方案是创建AsyncURLConnection类此代码,我发现某处在http://stackoverflow.com但现在找不到它。所以,我会给代码:

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 

.M

#import "AsyncURLConnection.h" 

@implementation AsyncURLConnection 

+ (id)requestWithMutable:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    return [[self alloc] initWithMutableRequest:request completeBlock:completeBlock errorBlock:errorBlock]; 
} 

+ (id)request:(NSString*)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    return [[self alloc] initWithRequest:requestUrl 
          completeBlock:completeBlock errorBlock:errorBlock]; 
} 

- (id)initWithRequest:(NSString *)requestUrl completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    if ((self=[super init])) { 
     data_ = [[NSMutableData alloc] init]; 
     completeBlock_ = [completeBlock copy]; 
     errorBlock_ = [errorBlock copy]; 
     NSURL *url = [NSURL URLWithString:requestUrl]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
     [NSURLConnection connectionWithRequest:request delegate:self]; 
    } 
    return self; 
} 

- (id)initWithMutableRequest:(NSMutableURLRequest *)request completeBlock:(completeBlock_t)completeBlock errorBlock:(errorBlock_t)errorBlock 
{ 
    if ((self=[super init])) { 
     data_ = [[NSMutableData alloc] init]; 
     completeBlock_ = [completeBlock copy]; 
     errorBlock_ = [errorBlock copy]; 
     [NSURLConnection connectionWithRequest:request delegate:self]; 
    } 
    return self; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    [data_ setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [data_ appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    completeBlock_(data_); 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    errorBlock_(error); 
} 


- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    if ([challenge previousFailureCount] == 0) 
    { 
     NSURLCredential *newCredential; 
     newCredential=[NSURLCredential credentialWithUser:@"someUser" 
               password:@"someUser" 
               persistence:NSURLCredentialPersistenceForSession]; 
     [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge]; 
     DLog(@"responded to authentication challenge"); 

    }else{ 
     DLog(@"previous authentication failure"); 
    } 
} 
在某些控制器

所以这个类可以使用:

+ (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); 
    }]; 
} 

希望这个代码可以帮助一些人。

谢谢大家的回答。