Hey I am working in kotlin multiplatform moblie. I want to ask that if api returns 401 status, I want to call refresh api. I am reading the doc to configure ktor but unable to understand this. Can someone guide me on this. I tried some code in my side, Can some one guide me any proper example how to achieve in my solution.
commonMain
expect fun httpClient(config: HttpClientConfig<*>.() -> Unit = {}): HttpClient
iOSMain
actual class Platform actual constructor() {
actual val versionCode =
platform.Foundation.NSBundle.mainBundle.infoDictionary?.get("CFBundleVersion").toString()
actual val accessToken = ""
}
androidMain
actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp) {
config(this)
install(ContentNegotiation) {
json(Json {
prettyPrint = true
ignoreUnknownKeys = true
explicitNulls = false
})
}
engine {
config {
retryOnConnectionFailure(true)
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(40, TimeUnit.SECONDS)
}
}
defaultRequest {
header("Client-Version", Platform().versionCode)
}
HttpResponseValidator {
validateResponse { response ->
when (response.status.value) {
401 -> {
}
}
}
}
install(Auth) {
bearer {
loadTokens {
BearerTokens(tokenProvider.accessToken, "")
}
}
}
}
Platform.kt
package com.example.kotlinmultiplatformsharedmodule
lateinit var provider: VersionAndroidProvider
lateinit var tokenProvider: AndroidToken
actual class Platform actual constructor() {
actual val versionCode get() = provider.version
actual val accessToken: String
get() = tokenProvider.accessToken
}
interface VersionAndroidProvider {
val version: String
}
interface AndroidToken {
val accessToken: String
}
- I need to call api, if api returns 401 status, I need to call refershToken api. After getting new accessToken from refreshToken api, I need to send this to api call.
- If refreshToken is giving 401 then I need to infrom my application to logout.
CodePudding user response:
If you use the Bearer provider in Ktor’s Authentication plugin then the refreshTokens
lambda will be called when a server returns 401. For more information read the documentation. Here is an incomplete example for your use case:
val client = HttpClient(Apache) {
install(Auth) {
bearer {
loadTokens {
BearerTokens("initial_access_token", "initial_refresh_token")
}
refreshTokens {
val response = client.get("https://example.com/get_token")
if (response.status == HttpStatusCode.Unauthorized) {
// logout
null
} else {
// get token from a response
BearerTokens("new_access_token", "new_refresh_token")
}
}
}
}
}