Android 在 Android 9(Pie)[android:targetSdkVersion = 28]之后将网络通信默认配置为禁止了明文传输。所谓明文传输就是Http请求,所以如果我们开发版本高于 28 ,打包之后我们 app 中的 Http 请求都无法成功,将会抛出
W/System.err: java.net.UnknownServiceException: CLEARTEXT communication to **** not permitted by network security policy
的错误。
android:usesCleartextTraffic
作为防止意外使用明文通信的手段
usesCleartextTraffic = true
且默认只信任系统级别证书,也就是我们在手机,设置-> 加密与凭据 ->信任的凭据 -> 系统tab下的所有证书。
如果我们采用默认配置,在我们升级 targetSdkVersion >= 24
后,我们就会遇到 Https 请求无法通过抓包工具配置的证书进行抓包的问题。
当我们升级 targetSdkVersion >= 28
就会出现无法所有的 Http 请求都无法响应的问题。
通过上一节网络配置版本变化的描述过程我们会发现,原因在于,24 以上不再信任用户证书了所以抓不了包了,28 以上无法进行http请求的原因是,系统默认不让进行明文传输了。
上面解释了这么配置就可以解决我们遇到的无法抓包和无法进行http请求的问题,我们大概可以理解为这个「网络安全配置」其实就是驾驭在代码之外的一个配置文件,程序读取配置来决定要不要校验http请求,是不是信任用户证书。
可以看出 google 虽然做了限制,但是也给了开发者自由。接下来就要凭着开发者的良心办事情了。
当然为了响应 Google 爸爸的要求和用户信息安全考虑,我们应该尽快升级所有的服务器域名为 Https 请求。但是对于有时候我们还是有一些域名为 Http 请求无法及时替换,就需要单独配置了。而且就正式的 APP 包,我们并不希望可以让其他人抓包,来给我们服务器带来安全隐患。
允许明文传输有两种配置方法第一个是在项目的主 module 的 AndroidManifest.xml
的 application 节点下配置
android:usesCleartextTraffic="true"
...>
...
但是这个属性在 Android 7.0 以后会被 android:networkSecurityConfig
属性覆盖。
添加在主工程中配置 res/xml/network_security_config.xml 如果没有可以新建一个文件。该配置会覆盖系统默认配置。所以我们可在这里配置我们自己的想要的网络配置。配置完成后我们需要在 AndroidManifest.xml
的 application 节点下配置
...>
...
network_security_config
可包含:
0 或 1 个
基本配置,也就是默认配置。 任意数量的
可以规定任意域名的请求配置 0 或 1 个
debug 模式下域名的配置,可用于调试下进行一些独立配置。
如果我们需要只需要支持某些域名下的明文传输,就可以利用 domain-config 来进行单独配置
example.com
cdn.example2.com
比如我们需要允许debug模式下允许抓包,也就是信任 user 证书可以进行下面的配置
...
在解决网络完全配置的时候突然想到了 Https 证书验证的问题,为什么我们APP本地没有安装证书,使用 OkHttp 也不用忽略证书验证,同样访问大多数网站的时候我们也都没有下载证书。就可以访问了。其实是因为 OkHttp 对于通过CA机构颁发的服务器证书,是默认通过校验的。一些公司的自签名证书就不行了。比如 12306。
今年年初我花一个月的时间收录整理了一套知识体系,如果有想法深入的系统化的去学习的,可以私信我【安卓】,我会把我收录整理的资料都送给大家,帮助大家更快的进阶。