iOS 支持Https 請(qǐng)求

因?yàn)?017年開(kāi)始,蘋(píng)果官方要求必須支持Https,ATS允許http加載 策略將被關(guān)閉。所以最近許多小伙伴應(yīng)該都在為適配而忙著搜集資料。最開(kāi)始看一些關(guān)于證書(shū)的東西,自己也是一臉懵逼。看了好幾遍,才大致懂了一點(diǎn)點(diǎn)。自己還去創(chuàng)建了證書(shū),搭建了tomcat進(jìn)行調(diào)試。雖然忙了半天效果不顯著,但是略有收獲,會(huì)進(jìn)行tomcat簡(jiǎn)單配置環(huán)境了(竊喜:只要有進(jìn)步都是好的)。不扯了,進(jìn)入正題。
  首先,一般小伙伴剛看到要適配的時(shí)候,一般會(huì)去查證書(shū)相關(guān)信息,其實(shí)先不用管證書(shū)問(wèn)題,等后臺(tái)配置好了,給你個(gè)證書(shū)就行了(我可沒(méi)有甩鍋給后臺(tái),主要自己要先把客戶端配置好,聯(lián)調(diào)最主要,也耗費(fèi)時(shí)間,有時(shí)間了再詳細(xì)了解證書(shū))。
  第一種最簡(jiǎn)單方式,后臺(tái)配置完成后,客戶端直接把請(qǐng)求改為https,ATS中Allow Arbitrary Loads改為NO,一行代碼沒(méi)有修改,驚奇的發(fā)現(xiàn),居然可以請(qǐng)求了。是不是很竊喜,暗自感嘆So easy! 小伙子高興的太早了。這種方式我理解為掛著https的旗幟,實(shí)際還是http。別人還是可以隨意的看你請(qǐng)求數(shù)據(jù)和返回?cái)?shù)據(jù)。可能有的小伙伴這時(shí)候有疑問(wèn)了,用charles抓包時(shí)候發(fā)現(xiàn),是沒(méi)辦法抓到數(shù)據(jù),顯示的是unkown,看返回?cái)?shù)據(jù)是亂碼,猿(樓主)又在瞎說(shuō)了。

抓取https請(qǐng)求.png

這是因?yàn)槟銢](méi)有啟用SSL 代理。右擊你的請(qǐng)求url,就會(huì)彈出選擇框,點(diǎn)擊Enable SSL Proxying。

開(kāi)啟SSL代理.png

至于這塊charles的配置,在此我就不詳細(xì)解釋了,有時(shí)間了再補(bǔ)充一下。自己查詢一下資料,主要就是手機(jī)添加charles ssl證書(shū),然后就可以看到跟請(qǐng)求http 一樣可以抓取數(shù)據(jù)了,所以樓主說(shuō)只是掛了https 的牌子,沒(méi)有做具體的事情。至于蘋(píng)果是否能夠?qū)徍送ㄟ^(guò),我也就不清楚了,反正樓主不當(dāng)?shù)谝粋€(gè)吃螃蟹的人(因?yàn)槌绦騿T要降低被拒風(fēng)險(xiǎn))。
  第二種方式,腳踏實(shí)地,一步一個(gè)腳印。先上代碼:

+ (AFSecurityPolicy*)customSecurityPolicy
{
    //先導(dǎo)入證書(shū)
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:certificate ofType:@"cer"];//證書(shū)的路徑
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    // AFSSLPinningModeCertificate 使用證書(shū)驗(yàn)證模式
    //AFSSLPinningModeNone: 代表客戶端無(wú)條件地信任服務(wù)器端返回的證書(shū)。
    //AFSSLPinningModePublicKey: 代表客戶端會(huì)將服務(wù)器端返回的證書(shū)與本地保存的證書(shū)中,PublicKey的部分進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。
    //AFSSLPinningModeCertificate: 代表客戶端會(huì)將服務(wù)器端返回的證書(shū)和本地保存的證書(shū)中的所有內(nèi)容,包括PublicKey和證書(shū)部分,全部進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    // allowInvalidCertificates 是否允許無(wú)效證書(shū)(也就是自建的證書(shū)),默認(rèn)為NO
    // 如果是需要驗(yàn)證自建證書(shū),需要設(shè)置為YES
    securityPolicy.allowInvalidCertificates = YES;
    //validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES;
    //假如證書(shū)的域名與你請(qǐng)求的域名不一致,需把該項(xiàng)設(shè)置為NO;如設(shè)成NO的話,即服務(wù)器使用其他可信任機(jī)構(gòu)頒發(fā)的證書(shū),也可以建立連接,這個(gè)非常危險(xiǎn),建議打開(kāi)。
    //置為NO,主要用于這種情況:客戶端請(qǐng)求的是子域名,而證書(shū)上的是另外一個(gè)域名。因?yàn)镾SL證書(shū)上的域名是獨(dú)立的,假如證書(shū)上注冊(cè)的域名是www.google.com,那么mail.google.com是無(wú)法驗(yàn)證通過(guò)的;當(dāng)然,有錢(qián)可以注冊(cè)通配符的域名*.google.com,但這個(gè)還是比較貴的。
    //如置為NO,建議自己添加對(duì)應(yīng)域名的校驗(yàn)邏輯。
    //對(duì)應(yīng)域名的校驗(yàn)我認(rèn)為應(yīng)該在url中去邏輯判斷。--》馮龍騰寫(xiě)
    securityPolicy.validatesDomainName = NO;
    if (certData) {
        securityPolicy.pinnedCertificates = [NSSet setWithObjects:certData, nil];
    }
    return securityPolicy;
}

這部分代碼是配置驗(yàn)證策略,摘自馮龍騰(雖然不知道哪位大神,還是要謝謝這么詳細(xì)的注釋。)然后把返回的securityPolicy賦值給AFHTTPSessionManager的securityPolicy屬性。有時(shí)間的朋友,可以看看AFN源碼了解一下底層驗(yàn)證策略。其實(shí)第一種方式,只添加了https請(qǐng)求,然后什么代碼也沒(méi)添加的方式,采取的是AFN 默認(rèn)驗(yàn)證策略

[AFSecurityPolicy defaultPolicy];

所以不用驚訝為啥能走的通,只不過(guò)采取的驗(yàn)證方式不同。這時(shí)候就可以跟后臺(tái)要證書(shū),進(jìn)行聯(lián)調(diào)了。
  一般只要證書(shū)沒(méi)有問(wèn)題,并且后臺(tái)支持了https,走通網(wǎng)絡(luò)請(qǐng)求,應(yīng)該問(wèn)題不大。最開(kāi)始我們使用的是自建證書(shū),后臺(tái)使用keytool生成證書(shū),當(dāng)時(shí)前端和后臺(tái)使用的是同一個(gè)證書(shū),看AFN源碼過(guò)程中,發(fā)現(xiàn)驗(yàn)證過(guò)程如果證書(shū)一致,也是可以正常請(qǐng)求的。但是不是CA證書(shū),繼續(xù)改進(jìn),使用openssl創(chuàng)建了自建的CA證書(shū)。自建CA證書(shū)和授權(quán)CA證書(shū),最大的區(qū)別,也是最簡(jiǎn)單的區(qū)別,就是你用瀏覽器訪問(wèn)時(shí)候,自建證書(shū)會(huì)顯示不是私密鏈接,點(diǎn)擊高級(jí),繼續(xù)進(jìn)行訪問(wèn),提示你不安全信息。

12306官網(wǎng).png

而授權(quán)CA證書(shū),則可以直接正常訪問(wèn)

百度.png

使用自建證書(shū)的時(shí)候,允許使用自建證書(shū)設(shè)置為YES,

securityPolicy.allowInvalidCertificates = YES;
AFSecurityPolicy  *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];

當(dāng)時(shí)這種情況我是沒(méi)有走通的,難道是沒(méi)有授權(quán)允許繼續(xù)訪問(wèn)按鈕?這就尷尬了,沒(méi)太多的時(shí)間去管這個(gè)了,跟后臺(tái)大哥說(shuō),咱還是用授權(quán)的CA證書(shū)吧,后臺(tái)大哥說(shuō),授權(quán)CA證書(shū)得money啊,一臉的不情愿,好在一不小心看到阿里有個(gè)可以申請(qǐng)免費(fèi)的CA證書(shū),當(dāng)時(shí)我是淚流滿面。證書(shū)搞定,然后聯(lián)調(diào)一切正常。
  這還沒(méi)完,要記得把自己用的第三方,友盟統(tǒng)計(jì),shareSDK,推送,熱部署JSPatch等等,更新到支持Https,如果有不支持https 請(qǐng)求的,要加入白名單(不知道蘋(píng)果審核允許不允許,但是目前沒(méi)想到好的方式)。還有網(wǎng)頁(yè)請(qǐng)求,也要注意一下。配置結(jié)束以后,用charles 抓包,查看一下有沒(méi)有請(qǐng)求失敗的,如果有,核查哪一部分的問(wèn)題。

Paste_Image.png

  最后提醒一下,授權(quán)證書(shū)是有過(guò)期時(shí)間的,要做好更新證書(shū)策略,策略問(wèn)題,目前我們已經(jīng)處理完了,每個(gè)公司不同,自己可以想一個(gè)比較完善的策略。希望大家的APP能夠順利上架。如果有理解不對(duì)的地方,請(qǐng)指出,不斷學(xué)習(xí)進(jìn)步的小碼農(nóng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容