Android - OkHttp 访问 https 的怪问题-三、配置

时间:2024-04-25 08:38:22

这里有个问题,是否只要发送 https 请求,就一定需要给 OkHttp 配置 https 校验呢?答案是非必须的,正常情况下 OkHttp 会使用默认的系统配置,用于访问一般的 https 请求足以,但往往有一些特殊情况,就需要我们在工程中进行单独配置并实现校验规则,例如以下几种情况:

  1. 服务端使用了非 CA 认证的私有 https 证书
  2. 服务端使用了过期的 https 证书
  3. 客户端支持某个 ssl 协议但是默认没有启用

好了,下面开始对 OkHttp 进行配置,大体分两步:

  1. 配置 SSLSocketFactory:用于指定支持某种 ssl 协议的 SocketFactory
  2. 配置 HostnameVerifier:用于检查证书中的主机名与使用该证书的服务器的主机名是否一致
val sslSocketFactory = NoSSLSocketClient.getTLSSocketFactory()
val x509TrustManager = NoSSLSocketClient.getX509TrustManager()
val hostnameVerifier = NoSSLSocketClient.getHostnameVerifier()

val okHttpClient = OkHttpClient.Builder()
    .sslSocketFactory(
        sslSocketFactory,
        x509TrustManager // 必须指定该参数,否则 Android 10 及以上版本会闪退
    )
    .hostnameVerifier(hostnameVerifier)
    .build()

这里主要看 sslSocketFactory 是怎么创建的,前面说过,https 证书大体分为 SSLTLS 两种协议,这里的 SSLSocketFactory 也一样,以下是两种协议对应的创建方式,它们仅仅只是在获取 SSLContext 实例时传的参数不同而已:

// SSL(不推荐)
public static SSLSocketFactory getSSLSocketFactory() {
   
    try {
   
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(