作者:Mitchell
一典勇、簡介
- HTTPS
即 HTTP + SSL 層歉甚,具體介紹在這里皂吮。 - 關(guān)于 iOS HTTPS 應(yīng)該是大多數(shù)人想要的
二筋夏、HTTPS與HTTP的區(qū)別
- 這里用兩張圖來介紹兩者的區(qū)別:
-
HTTP:當(dāng)客戶端發(fā)送請求蒂胞,那么服務(wù)器會(huì)直接返回?cái)?shù)據(jù)。
-
HTTPS:當(dāng)客戶端第一次發(fā)送請求的時(shí)候条篷,服務(wù)器會(huì)返回一個(gè)包含公鑰的受保護(hù)空間(也成為證書)骗随,當(dāng)我們發(fā)送請求的時(shí)候,公鑰會(huì)將請求加密再發(fā)送給服務(wù)器赴叹,服務(wù)器接到請求之后鸿染,用自帶的私鑰進(jìn)行解密,如果正確再返回?cái)?shù)據(jù)乞巧。這就是 HTTPS 的安全性所在涨椒。
-
三、實(shí)例
#import "ViewController.h"
@interface ViewController ()<NSURLSessionDataDelegate>
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSURL *url = [NSURL URLWithString:@"https://kyfw.12306.cn/otn/leftTicket/init"];
// NSURL *url = [NSURL URLWithString:@"https://www.apple.com/"];
// NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
[task resume];
}
#pragma mark - NSURLSessionDataDelegate
/*
// 只要訪問的是HTTPS的路徑就會(huì)調(diào)用
// 該方法的作用就是處理服務(wù)器返回的證書, 需要在該方法中告訴系統(tǒng)是否需要安裝服務(wù)器返回的證書
// NSURLAuthenticationChallenge : 授權(quán)質(zhì)問
//+ 受保護(hù)空間
//+ 服務(wù)器返回的證書類型
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
// NSLog(@"didReceiveChallenge");
// NSLog(@"%@", challenge.protectionSpace.authenticationMethod);
// 1.從服務(wù)器返回的受保護(hù)空間中拿到證書的類型
// 2.判斷服務(wù)器返回的證書是否是服務(wù)器信任的
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(@"是服務(wù)器信任的證書");
// 3.根據(jù)服務(wù)器返回的受保護(hù)空間創(chuàng)建一個(gè)證書
// void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)
// 代理方法的completionHandler block接收兩個(gè)參數(shù):
// 第一個(gè)參數(shù): 代表如何處理證書
// 第二個(gè)參數(shù): 代表需要處理哪個(gè)證書
//創(chuàng)建證書
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
// 4.安裝證書 completionHandler(NSURLSessionAuthChallengeUseCredential , credential);
}
}
*/
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
//AFNetworking中的處理方式
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;
//判斷服務(wù)器返回的證書是否是服務(wù)器信任的
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
/*disposition:如何處理證書
NSURLSessionAuthChallengePerformDefaultHandling:默認(rèn)方式處理
NSURLSessionAuthChallengeUseCredential:使用指定的證書 NSURLSessionAuthChallengeCancelAuthenticationChallenge:取消請求
*/
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
//安裝證書
if (completionHandler) {
completionHandler(disposition, credential);
}
}
// 接收到服務(wù)器的響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
NSLog(@"didReceiveResponse");
completionHandler(NSURLSessionResponseAllow);
}
// 接收到服務(wù)器返回的數(shù)據(jù)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData");
}
// 請求完畢
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
}
@end
四绽媒、問題
- 有時(shí)采用HTTPS 無法接受數(shù)據(jù)蚕冬,是因?yàn)樘O果將http使用的是TLS 1.2 SSL 加密請求數(shù)據(jù),而服務(wù)器有的時(shí)候使用的還是TLS 1.1
- 解決辦法:在 info.plist 中添加
- <key>NSAppTransportSecurity</key><dict>
<key>NSAllowsArbitraryLoads</key>
<true/></dict>