Some times mobile developers use a development server with invalid or expired SSL certificate.
In case of use ktor as http client you can ignore SSL errors for development environment in the following way:
Example
build.gradle.kts
kotlin {
android()
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.contains("simulator") == true)
::iosX64
else
::iosArm64
iOSTarget("ios") {
binaries {
framework {
baseName = "shared"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9-native-mt")
implementation("io.ktor:ktor-client-core:1.3.2-1.4.0-rc")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9-native-mt")
implementation("io.ktor:ktor-client-android:1.3.2-1.4.0-rc")
implementation("io.ktor:ktor-client-core-jvm:1.3.2-1.4.0-rc")
}
}
val androidTest by getting
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:1.3.2-1.4.0-rc")
implementation("io.ktor:ktor-client-core:1.3.2-1.4.0-rc")
}
}
val iosTest by getting
}
}
Shared
val httpClient = HttpClient(httpEngine())
expect fun httpEngine(): HttpClientEngine
Android
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.android.Android
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.X509TrustManager
actual fun httpEngine(): HttpClientEngine = Android.create {
sslManager = { conn ->
val sslContext: SSLContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
conn.sslSocketFactory = sslContext.socketFactory
conn.hostnameVerifier = HostnameVerifier { _, _ -> true }
}
}
private val trustAllCerts: Array<X509TrustManager> = arrayOf(
object : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(
chain: Array<X509Certificate?>?,
authType: String?
) {}
@Throws(CertificateException::class)
override fun checkServerTrusted(
chain: Array<X509Certificate?>?,
authType: String?
) {}
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
)
iOS
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.ios.Ios
import platform.Foundation.NSURLCredential
import platform.Foundation.NSURLSessionAuthChallengeUseCredential
import platform.Foundation.create
import platform.Foundation.serverTrust
actual fun httpEngine(): HttpClientEngine = Ios.create {
handleChallenge { _, _, challenge, completionHandler ->
completionHandler(
NSURLSessionAuthChallengeUseCredential,
NSURLCredential.create(challenge.protectionSpace.serverTrust)
)
}
}
Result
As a result, you can make https requests to the server without a valid SSL certificate.
ATTENTION!: Don’t use this approach in PRODUCTION!