WWDC 15 提出的 ATS (App Transport Security) 是 Apple 在推進網(wǎng)絡(luò)通訊安全的一個重要方式。在 iOS 9 和 OS X 10.11 中,默認(rèn)情況下非 HTTPS 的網(wǎng)絡(luò)訪問是被禁止的。當(dāng)然,因為這樣的推進影響面非常廣,作為緩沖,我們可以在 Info.plist 中添加NSAppTransportSecurity字典并且將NSAllowsArbitraryLoads設(shè)置為YES來禁用 ATS。相信大家都已經(jīng)對這個非常熟悉了,因為我自己也維護了一些網(wǎng)絡(luò)相關(guān)的框架,所以我還自己準(zhǔn)備了一個小腳本來快速關(guān)閉 ATS。
不過,WWDC 16 中,Apple 表示將繼續(xù)在 iOS 10 和 macOS 10.12 里收緊對普通 HTTP 的訪問限制。從 2017 年 1 月 1 日起,所有的新提交 app 默認(rèn)是不允許使用NSAllowsArbitraryLoads來繞過 ATS 限制的,也就是說,我們最好保證 app 的所有網(wǎng)絡(luò)請求都是 HTTPS 加密的,否則可能會在應(yīng)用審核時遇到麻煩。
本文寫作的時間點 (2016 年 6 月 17 日),這方面的相關(guān)規(guī)定和幾個事實如下。但是似乎 Apple 安全部門對現(xiàn)在的情況也有些內(nèi)部沖突,所以不排除在正式版中發(fā)生改變的可能性。我也會對此繼續(xù)關(guān)注,并在需要的時候?qū)Ρ疚倪M行更新。如果您發(fā)現(xiàn)了下面所述和事實不符的話,也歡迎留言提出,我會進行修正。
默認(rèn)情況下你的 app 可以訪問加密足夠強 (TLSv1.2 以上,AES-128 和 SHA-2 以及 ECDHC 等) 的 HTTPS 內(nèi)容。這對所有的網(wǎng)絡(luò)請求都有效,包括NSURLSession,UIWebView以及WKWebView等。
你依然可以添加NSAllowsArbitraryLoads為YES來禁用 ATS,不過如果你這么做的話,需要在提交 app 時進行說明,為什么需要訪問非 HTTPS 內(nèi)容。一般來說,可能類似瀏覽器類的 app 比較容易能通過。
相比于使用NSAllowsArbitraryLoads將全部 HTTP 內(nèi)容開放,選擇使用NSExceptionDomains來針對特定的域名開放 HTTP 應(yīng)該要相對容易過審核。“需要訪問的域名是第三方服務(wù)器,他們沒有進行 HTTPS 對應(yīng)”會是審核時的一個可選理由,但是這應(yīng)該只需要針對特定域名,而非全面開放。如果訪問的是自己的服務(wù)器的話,可能這個理由會無法通過。
對于網(wǎng)頁瀏覽和視頻播放的行為,iOS 10 中新加入了NSAllowsArbitraryLoadsInWebContent鍵。通過將它設(shè)置為YES,可以讓你的 app 中的WKWebView和使用AVFoundation播放的在線視頻不受 ATS 的限制。這也應(yīng)該是絕大多數(shù)使用了相關(guān)特性的 app 的選擇。但是壞消息是這個鍵在 iOS 9 中并不會起作用。
總結(jié)一下就是,對于 API 請求,基本上是必須使用 HTTPS 的,特別是如果你們自己可以管理服務(wù)器的話。可能需要后端的同學(xué)盡快升級到 HTTPS (不過話說雖然是用 Let's Encrypt 的,我一個個人博客都啟用 HTTPS 了,作為 API 的用戶服務(wù)器,還不開 HTTPS 真有點說不過去)。如果你的 app 只支持 iOS 10,并且有用戶可以自由輸入網(wǎng)址進行瀏覽的功能,或者是在線視頻音頻播放功能的話,簡單地加入NSAllowsArbitraryLoadsInWebContent,并且將組件換成WKWebKit或者AVFoundation就可以了。如果你還需要支持 iOS 9,并且需要訪問網(wǎng)頁和視頻的話,可能只能去開啟NSAllowsArbitraryLoads然后提交時進行說明,并且看 Apple 審核員的臉色決定讓不讓通過了。除了WKWebKit以外,另外一個訪問網(wǎng)頁的選擇是使用SFSafariViewController。因為其實SFSafariViewController就是一個獨立于 app 的 Safari 進程,所以它完全不受 ATS 的限制。
另外,當(dāng)NSAllowsArbitraryLoads和NSAllowsArbitraryLoadsInWebContent同時存在時,根據(jù)系統(tǒng)不同,表現(xiàn)的行為也會不一樣。簡單說,iOS 9 只看NSAllowsArbitraryLoads,而 iOS 10 會先看NSAllowsArbitraryLoadsInWebContent。在 iOS 10 中,要是NSAllowsArbitraryLoadsInWebContent存在的話,就忽略掉NSAllowsArbitraryLoads,如果它不存在,則遵循NSAllowsArbitraryLoads的設(shè)定。說起來可能有點復(fù)雜,我在這里總結(jié)了一下根據(jù)NSAppTransportSecurity中設(shè)定條件不同,所對應(yīng)的系統(tǒng)版本和請求組件的行為的不同,可以作為你設(shè)置這個字典時的參考。
該列表是根據(jù) Apple prerelease 的文檔中關(guān)于NSAppTransportSecurity和NSAllowsArbitraryLoadsInWebContent部分的描述作出的。如果您發(fā)現(xiàn)這個行為發(fā)生了變化,或者上面的列表存在問題,歡迎留言,我會進行更正。
關(guān)于UIWebView是否也可以在NSAllowsArbitraryLoadsInWebContent為YES時訪問 HTTP,Apple 內(nèi)部似乎也在爭論,但是個人認(rèn)為是時候淘汰UIWebView了。如果沒有特殊的什么需求的話,盡早將UIWebView全部換為WkWebView會是明智的選擇。
不得不說,Apple 使用自己現(xiàn)在的強勢地位,在推動技術(shù)進步上的做的努力是有目共睹的。不論是前幾天強制支持 IPv6,還是現(xiàn)在的 HTTPS,其實都不是很容易就能作出的決定。而為用戶構(gòu)建一個更安全的使用環(huán)境,可能不僅是 Apple 單方面可以做的,也是需要開發(fā)者來配合的一件事情。盡快適配更進步和安全的使用方式,會是一件雙贏的事情。
轉(zhuǎn)自?OneV`s Den