IOSHTTPS网络请求的单向验证

HTTPS - SSL加密

使用AFNetWoking进行证书的验证

//

//  PPHTTPRequestOperationManager.m

//  PPDate

//

//  Created by 郭远强 on 16/3/30.

//  Copyright © 2016年 郭远强. All rights reserved.

//

 

#import "PPHTTPRequestOperationManager.h"

#import "PPTaskEngine.h"

#import "PPHTTPRequestSerializer.h"

#import "PPHTTPResponseSerializer.h"

#import <AFNetworking/AFNetworkActivityIndicatorManager.h>

 

@interface NSDictionary (description)

 

- (NSString *)descriptionWithPrefix:(NSMutableString *)prefix;

 

@end

 

@interface PPHTTPRequestOperationManager ()

@property (nonatomic,strong) PPTaskEngine * engine;

@end

 

@implementation PPHTTPRequestOperationManager

 

+(instancetype)manager

{

    static dispatch_once_t token;

    static PPHTTPRequestOperationManager * _manager;

    dispatch_once(&token, ^{

        

        _manager = [[[self class] alloc] initWithBaseURL:[NSURL URLWithString:kPPUrlHttp]];

        // _manager.engine = [PPTaskEngine sharedEngine];

        

    });

    return _manager;

}

- (instancetype)initWithBaseURL:(NSURL *)url

{

    self = [super initWithBaseURL:url];

    

    if (self)

    {

        

        self.requestSerializer = [PPHTTPRequestSerializer serializer];

        self.responseSerializer = [PPHTTPResponseSerializer serializer];

        self.responseSerializer.acceptableContentTypes = [self.responseSerializer.acceptableContentTypes setByAddingObjectsFromArray:@[@"text/plain",@"text/html"]];

        

        

        

        [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];

        self.requestSerializer.timeoutInterval = 30;

        //  self.requestSerializer.allowsCellularAccess = YES;

        

#ifdef openHttpsSSL

        [self setSecurityPolicy:[self customSecurityPolicy]];

        WS(weakSelf);

        [self setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing  _Nullable * _Nullable credential) {

            return [weakSelf p_CertificateCalibrateByAuthenticationChallenge:challenge completionHandler:^(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential) {

                

            }];

            

        }];

#endif

        

    }

    return self;

}

 

//证书校验

- (NSURLSessionAuthChallengeDisposition)p_CertificateCalibrateByAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler

{

    NSURLCredential * credential = nil;

    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;

    // 判断服务器的证书是否被服务器所信任

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])

    {

        BOOL ret = [self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host];

        if (ret) {

            credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];

            disposition =NSURLSessionAuthChallengeUseCredential;

        }else{

            [challenge.sender cancelAuthenticationChallenge:challenge];

            disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;

            

            PPTLogInfo(@"证书不一致");

        }

        

    }

    //安装证书

    if (completionHandler) {

        completionHandler(disposition, credential);

    }

    return disposition;

    

}

 

 

 

- (AFSecurityPolicy*)customSecurityPolicy

{

    // /先导入证书

    //NSString *cerPath = [[NSBundle mainBundle] pathForResource:certificate ofType:@"cer"];

    //证书的路径

    //NSData *certData = [NSData dataWithContentsOfFile:cerPath];

    

    // AFSSLPinningModeCertificate 使用证书验证模式

    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

    

    // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO

    // 如果是需要验证自建证书,需要设置为YES

    securityPolicy.allowInvalidCertificates = YES;

    

    //validatesDomainName 是否需要验证域名,默认为YES;

    //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。

    //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。

    

    

    securityPolicy.validatesDomainName = NO;

    //if (certData) {

    // securityPolicy.pinnedCertificates = [NSSet setWithArray:@[certData]];

    //}

    

    

    return securityPolicy;

}

 

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request

                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler

{

    

    

    void (^successBlock)(NSURLResponse *, id,id) = ^( NSURLResponse *operation, id responseObject,NSError *error)

    {

        if (completionHandler) {

            completionHandler(operation,responseObject,error);

        }

        [self showAlertViewWithRequest:request responseObject:responseObject error:nil];

    };

    

    void (^failureBlock)(NSURLResponse *, id,id) = ^( NSURLResponse *operation, id responseObject,NSError * error)

    {

        if (completionHandler) {

            completionHandler(operation, nil,error);

        }

        [self showAlertViewWithRequest:request responseObject:nil error:error];

    };

    

    return [super dataTaskWithRequest:request completionHandler:successBlock?successBlock:failureBlock];

    

}

 

- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure

{

    

    void (^successBlock)(NSURLSessionDataTask *,id) = ^( NSURLSessionDataTask *operation, id responseObject)

    {

        if (success) {

            success(operation,responseObject);

            

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:responseObject error:nil];

    };

    

    void (^failureBlock)(NSURLSessionDataTask *, id) = ^( NSURLSessionDataTask *operation,NSError * error)

    {

        if (failure) {

            failure(operation,error);

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:nil error:error];

    };

    

    return [super GET:URLString parameters:parameters progress:downloadProgress success:successBlock failure:failureBlock];

    

    

}

 

- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure

{

    

    void (^successBlock)(NSURLSessionDataTask *,id) = ^( NSURLSessionDataTask *operation, id responseObject)

    {

        if (success) {

            success(operation,responseObject);

            

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:responseObject error:nil];

    };

    

    void (^failureBlock)(NSURLSessionDataTask *, id) = ^( NSURLSessionDataTask *operation,NSError * error)

    {

        if (failure) {

            failure(operation,error);

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:nil error:error];

    };

    

    return   [super  POST:URLString parameters:parameters progress:uploadProgress success:successBlock failure:failureBlock];

    

}

 

- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id<AFMultipartFormData> _Nonnull))block progress:(void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure

{

    

    void (^successBlock)(NSURLSessionDataTask *,id) = ^( NSURLSessionDataTask *operation, id responseObject)

    {

        if (success) {

            success(operation,responseObject);

            

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:responseObject error:nil];

    };

    

    void (^failureBlock)(NSURLSessionDataTask *, id) = ^( NSURLSessionDataTask *operation,NSError * error)

    {

        if (failure) {

            failure(operation,error);

        }

        [self showAlertViewWithRequest:operation.currentRequest responseObject:nil error:error];

    };

    return  [super POST:URLString parameters:parameters constructingBodyWithBlock:block progress:uploadProgress success:successBlock failure:failureBlock];

    

}

 

 

 

//- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure

//{

//    void (^successBlock)(AFHTTPRequestOperation *, id) = ^( AFHTTPRequestOperation *operation, id responseObject)

//    {

//        if (success) {

//            success(operation, responseObject);

//        }

//        [self showAlertViewWithRequest:request responseObject:responseObject error:nil];

//    };

//

//    void (^failureBlock)(AFHTTPRequestOperation *, NSError *) = ^( AFHTTPRequestOperation *operation, NSError * error)

//    {

//        if (failure) {

//            failure(operation, error);

//        }

//        [self showAlertViewWithRequest:request responseObject:nil error:error];

//    };

//

//    return [super HTTPRequestOperationWithRequest:request success:successBlock failure:failureBlock];

//}

 

- (void)showAlertViewWithRequest:(NSURLRequest *)request responseObject:(id)responseObject error:(NSError *)error

{

    if(![responseObject isKindOfClass:[NSDictionary class]])

    {

        return;

    }

    PPHTTPResponse *response = [MTLJSONAdapter modelOfClass:[PPHTTPResponse class] fromJSONDictionary:responseObject error:&error];

    if (response.code.integerValue == 402 && [response.message containsString:@"token"]) {

        //[[NSNotificationCenter defaultCenter] postNotificationName:kPPObserverTokenInvalid object:nil];

        

        [[PPDataEngine shareEngine]logoutEasemodLogoutCompletion:^(EMError *aError) {

            

        }];

        

    }

    if (!kPPShowRequestAlert) {

        return ;

    }

    NSDictionary *param = [self paramsWithQuery:[request.URL query]];

    NSString *baseUrl = [[request.URL absoluteString] substringToIndex:[[request.URL absoluteString] length] - [[request.URL query] length] - 1];

    NSString *string = [NSString stringWithFormat:@"服务器地址\n%@\n请求参数\n%@\n返回结果\n%@", baseUrl, [param descriptionWithPrefix:nil] ,error ? error : [responseObject descriptionWithPrefix:nil]];

    

    EVDialogView *dialogView = PPLoadNib(@"EVDialogView");

    [dialogView showWithText:string];

}

 

- (NSDictionary *)paramsWithQuery:(NSString *)aQuery

{

    if (aQuery.length <= 0)

    {

        return nil;

    }

    

    NSArray *kvPairs = [aQuery componentsSeparatedByString:@"&"];

    NSMutableDictionary *params = [NSMutableDictionary dictionary];

    for (NSString *kvPair in kvPairs)

    {

        NSArray *kvArr = [kvPair componentsSeparatedByString:@"="];

        if ([kvArr count] > 1)

        {

            NSString *value = [kvArr objectAtIndex:1];

            //url解码

            value =  [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            [params setObject:value forKey:[kvArr firstObject]];

            

        }

    }

    return params;

}

 

@end

 

 

@implementation NSDictionary (description)

 

- (NSString *)descriptionWithPrefix:(NSMutableString *)prefix

{

    if (!prefix) {

        prefix = [[NSMutableString alloc] init];

    }

    NSArray *allKeys = [self allKeys];

    NSString *curPrefix = [NSString stringWithString:prefix];

    NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"%@{\n", curPrefix];

    for (NSString *key in allKeys) {

        id value = self[key];

        if ([value isKindOfClass:[NSDictionary class]]) {

            

            [prefix appendFormat:@"\t"];

            NSString *valueString = [value descriptionWithPrefix:prefix];

            [str appendFormat:@"%@\t\"%@\" : %@\n", curPrefix, key, valueString];

        }else if ([value isKindOfClass:[NSArray class]])

        {

            [prefix appendFormat:@"\t"];

            [str appendFormat:@"%@\t\"%@\" : (",curPrefix, key];

            int i = 0;

            for (id subValue in value) {

                NSString *substring = [subValue descriptionWithPrefix:prefix];

                if (i == 0) {

                    [str appendFormat:@"\n%@",substring];

                }else

                {

                    [str appendFormat:@", \n%@", substring];

                }

                i ++;

            }

            [str appendFormat:@"\n%@\t)\n", curPrefix];

        }else

        {

            [str appendFormat:@"%@\t\"%@\" : \"%@\"\n",curPrefix, key, value];

        }

    }

    [str appendFormat:@"%@}", curPrefix];

    

    return str;

}

 

 

 

@end

 

posted @ 2017-04-01 10:55  tiankongzhicheng  阅读(416)  评论(0编辑  收藏  举报