Android 在 Android 9(Pie)[android:targetSdkVersion = 28]以後將網絡通訊默認配置爲禁止了明文傳輸。所謂明文傳輸就是Http請求,因此若是咱們開發版本高於 28 ,打包以後咱們 app 中的 Http 請求都沒法成功,將會拋出java
W/System.err: java.net.UnknownServiceException: CLEARTEXT communication to **** not permitted by network security policy
複製代碼
的錯誤。android
android:usesCleartextTraffic
做爲防止意外使用明文通訊的手段<!-- 默認容許全部明文通訊 -->
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<!-- 信任系統預裝 CA 證書 -->
<certificates src="system" />
<!-- 信任用戶添加的 CA 證書,Charles 和 Fiddler 抓包工具安裝的證書屬於此類 -->
<certificates src="user" />
</trust-anchors>
</base-config>
複製代碼
<!-- 默認容許全部明文通訊 -->
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<!-- 信任系統預裝 CA 證書 -->
<certificates src="system" />
</trust-anchors>
</base-config>
複製代碼
usesCleartextTraffic = true
且默認只信任系統級別證書,也就是咱們在手機,設置-> 加密與憑據 ->信任的憑據 -> 系統tab下的全部證書。<!-- 默認禁止全部明文通訊 -->
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<!-- 信任系統預裝 CA 證書 -->
<certificates src="system" />
</trust-anchors>
</base-config>
複製代碼
若是咱們採用默認配置,在咱們升級 targetSdkVersion >= 24
後,咱們就會遇到 Https 請求沒法經過抓包工具配置的證書進行抓包的問題。git
當咱們升級 targetSdkVersion >= 28
就會出現沒法全部的 Http 請求都沒法響應的問題。github
經過上一節網絡配置版本變化的描述過程咱們會發現,緣由在於,24 以上再也不信任用戶證書了因此抓不了包了,28 以上沒法進行http請求的緣由是,系統默認不讓進行明文傳輸了。安全
上面解釋了這麼配置就能夠解決咱們遇到的沒法抓包和沒法進行http請求的問題,咱們大概能夠理解爲這個「網絡安全配置」其實就是駕馭在代碼以外的一個配置文件,程序讀取配置來決定要不要校驗http請求,是否是信任用戶證書。bash
能夠看出 google 雖然作了限制,可是也給了開發者自由。接下來就要憑着開發者的良心辦事情了。服務器
固然爲了響應 Google 爸爸的要求和用戶信息安全考慮,咱們應該儘快升級全部的服務器域名爲 Https 請求。可是對於有時候咱們仍是有一些域名爲 Http 請求沒法及時替換,就須要單獨配置了。並且就正式的 APP 包,咱們並不但願可讓其餘人抓包,來給咱們服務器帶來安全隱患。網絡
容許明文傳輸有兩種配置方法第一個是在項目的主 module 的 AndroidManifest.xml
的 application 節點下配置app
<application
...
<!--容許 -->
android:usesCleartextTraffic="true"
...>
...
</application>
複製代碼
可是這個屬性在 Android 7.0 之後會被 android:networkSecurityConfig
屬性覆蓋。dom
添加在主工程中配置 res/xml/network_security_config.xml 若是沒有能夠新建一個文件。該配置會覆蓋系統默認配置。因此咱們可在這裏配置咱們本身的想要的網絡配置。配置完成後咱們須要在 AndroidManifest.xml
的 application 節點下配置
<application
...
<application android:networkSecurityConfig="@xml/network_security_config"
<!--7.0後會被覆蓋-->
<!--android:usesCleartextTraffic="true"-->
...>
...
</application>
複製代碼
network_security_config
可包含:
0 或 1 個 <base-config>
基本配置,也就是默認配置。 任意數量的 <domain-config>
能夠規定任意域名的請求配置 0 或 1 個 <debug-overrides>
debug 模式下域名的配置,可用於調試下進行一些獨立配置。
若是咱們須要只須要支持某些域名下的明文傳輸,就能夠利用 domain-config 來進行單獨配置
<network-security-config>
<!--容許有多個 domain-confing 該domain-config 下的domain 域名容許明文傳輸-->
<domain-config cleartextTrafficPermitted="true">
<!--includeSubdomains 是不是包含子域名-->
<domain includeSubdomains="true">example.com</domain>
<domain includeSubdomains="true">cdn.example2.com</domain>
</domain-config>
<!--除了domain-config 的標籤下的域名都不容許明文傳輸-->
<base-config cleartextTrafficPermitted="false" />
</network-security-config>
複製代碼
好比咱們須要容許debug模式下容許抓包,也就是信任 user 證書能夠進行下面的配置
<network-security-config>
<!-- 支持 Android 7.0 以上調試時,信任 Charles 等抓包工具的證書 -->
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
...
</network-security-config>
複製代碼
對於更多的配置信息你們能夠參照google文檔:網絡徹底配置 一節。
在解決網絡徹底配置的時候忽然想到了 Https 證書驗證的問題,爲何咱們APP本地沒有安裝證書,使用 OkHttp 也不用忽略證書驗證,一樣訪問大多數網站的時候咱們也都沒有下載證書。就能夠訪問了。實際上是由於 OkHttp 對於經過CA機構頒發的服務器證書,是默認經過校驗的。一些公司的自簽名證書就不行了。好比 12306。
#參考