大家好,小弟最近在IOS端遇到一個問題一直沒能解決,因為我才出來沒多久,所以困擾了很久,希望能得到大家的幫助。
問題是這樣的,根據客戶的需要,APP端在跟后臺通信的時候需要做證書的效驗以保證通信的安全。我們的證書是從CA機構買的,因為我是用的是AFNetworking框架,然后我就根據一些資料和文檔寫。
1.我先是把后臺給我的證書(.cer格式的)拖到了我的工程目錄里面。server.cer是正確的證書,為了驗證,我自建了一個假的證書:thesis_client.cer
2.一開始我使用的是AFHTTPRequestOperationManager,然后根據查閱的一些資料上完成了代碼,給AFHTTPRequestOperationManager設置了AFSecurityPolicy屬性,代碼如下:
這個時候我遇到了第一個問題:
問題1:我查看了一下AFNetworking的源碼,發現,當開始一個正常的驗證流程的時候是會執行AFN的一個方法:evaluateServerTrust
但是打斷點走下來發現程序沒有執行到這個方法,所以如果一開始我導入到工程里面的是自建的假的thesis_client.cer證書也可以訪問到我的后臺,也能拿到數據,但是調試下來發現,如果我程序開著過個一段時間(大約15到20分鐘左右)再次發送網絡請求的時候,這時候AFN的走了驗證方法evaluateServerTrust,這是我遇到的第一個問題。
3.因為這樣肯定不是想要的結果,所以我就重新嘗試其他的方法,就不用AFHTTPRequestOperationManager,換成了AFHTTPSessionManager,也對他進行了同樣的AFSecurityPolicy設置,代碼跟設置AFHTTPRequestOperationManager是一樣的,這次發現,當我第一次與我們的后臺建立鏈接的時候就走到了AFN的驗證方法evaluateServerTrust。而且也能有正確的結果,就是正確的證書server.cer通過了驗證而 thesis_client. cer沒有通過驗證。
但是這個時候我又遇到了兩個問題:
a.我發現只有在第一次與后臺建立鏈接的時候才會進行驗證,后面的請求就都不進行驗證了
b.在測試的發現,上面的代碼在IOS7和IOS9上是可行的(先不管是否只有第一次的進行驗證),至少每次第一次請求的時候都會進行驗證,但是在IOS8下,卻沒有走AFN的驗證方法evaluateServerTrust,所以在IOS8下使用假證書thesis_client.cer也可以訪問到后臺。
4.后來我想AFHTTPSessionManager也是使用的NSURLSession,我干脆直接用NSURLSession寫個demo試試看,我看了一下NSURLSession的文檔,看見了他的didReceiveChallenge方法
因為我是個新手很多東西都不是很理解,就覺得大致的意思就是,當收到驗證要求的時候就會走NSURLSession的這個代理,下面描述的第二項,說當第一次與遠程服務器建立鏈接的認證證書,不知道這個是不是就是我上面遇到的問題,IOS9和IOS7下只有第一次走認證方法,之后的請求都沒有走的原因,還希望大家點播我一下。
然后我就開始寫demo了
測試了一下發現,果然和上面遇到的情況一下,IOS9和IOS7下走了NSURLSession的代理didReceiveChallenge,在IOS8下沒有走。然后我就更加疑惑了,不知道那里出問題了。
后來我發現了兩個情況出現了:
a.上面我自己寫的NSURLSession請求的地@"https://gis.map2bit.com/mobile/getMyProject"就是我們自己后臺的地址,后來我把這個地址改掉了,改成github的官網地址
發現在IOS8下走到了didReceiveChallenge的代理里面了,后來我又嘗試https://baidu.com和Adobe的官網,發現都是可以正常走到didReceiveChallenge這個代理,唯獨我們自己的后臺不行,這個時候我就在想是不是后臺的原因。。。。
b. 后來我打算先看看我們的后臺地址是不是跟github、百度他們的有什么不一樣的地方,我就用Charles試了試,在試的過程并沒有發現有什么不一樣的地方,但是發現一個問題,我用Charles針對我們后臺的地址設置了SSL Proxying來截取SSL請求,發現在IOS8下能走到didReceiveChallenge這個代理