AFNetworking 适配https 摘自http://www.jianshu.com/p/f312a84a944c
ATS是在2015年由苹果引入的强化网络传输安全的标准,要求所有的App在从Web端获取数据的时候都要使用安全的HTTPS链接,并进一步强调要使用最新的TLS1.2版本的HTTPS。
首先需要服务器端升级到https,拿到服务器哥们提供的server.pem证书文件,并导入到项目中
+ (AFSecurityPolicy*)customSecurityPolicy
{
//先导入证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//AFSSLPinningModeNone不做任何验证,只要服务器返回了证书就行
//AFSSLPinningModePublicKey只验证公钥
//AFSSLPinningModeCertificate 所有内容一致才能通过
// allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = @[certData];
return securityPolicy;
}
+ (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
// 1.获得请求管理者
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
// 2.申明返回的结果是text/html类型
mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
// 加上这行代码,https ssl 验证。
[mgr setSecurityPolicy:[NetworkHelpManager customSecurityPolicy]];
// 3.发送POST请求
[mgr POST:url parameters:params
success:^(NSURLSessionDataTask *operation, id responseObj) {
if (success) {
success(responseObj);
}
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
}
AFN常见错误
//1.创建一个管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//1.0 改请求的默认的序列化方式 改成JSON格式的请求(请求为json格式的二进制)
//会把字典,数组转化成json格式的二进制传给服务器。
//默认情况下是普通的二进制,实现此方法改为JSON格式的二进制
manager.requestSerializer = [AFJSONRequestSerializer serializer];
//1.1 改默认的响应反序列化方式 改为普通二进制(服务器返回的是二进制,afn不做处理)。
//默认情况下 afn会做二进制转为json的格式的处理。然后我们自己把json转成数组,或字典。
//实现此方法后不做处理,直接将二进制说句给你。也不再需要1.2 增加默认的返回方式(JSON)的可接收的类型。
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//1.2 增加默认的返回方式(JSON)的可接收的类型
//manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/plain"];
常见问题
注意:如果服务器升级到TLS1.1还是不行的,因为苹果要求使用TLS1.2 SSL加密请求数据。会造成无法接受数据