Apply ktor-client-auth library to auto refresh token
This commit is contained in:
+26
-31
@@ -10,6 +10,9 @@ import io.ktor.client.engine.darwin.Darwin
|
||||
import io.ktor.client.plugins.DefaultRequest
|
||||
import io.ktor.client.plugins.HttpSend
|
||||
import io.ktor.client.plugins.HttpTimeout
|
||||
import io.ktor.client.plugins.auth.Auth
|
||||
import io.ktor.client.plugins.auth.providers.BearerTokens
|
||||
import io.ktor.client.plugins.auth.providers.bearer
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.plugins.logging.LogLevel
|
||||
import io.ktor.client.plugins.logging.Logger
|
||||
@@ -18,22 +21,40 @@ import io.ktor.client.plugins.plugin
|
||||
import io.ktor.client.request.header
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
actual fun createPlatformHttpClient(
|
||||
tokenManager: TokenManager,
|
||||
authApi: AuthApi?
|
||||
): HttpClient {
|
||||
val client = HttpClient(Darwin) {
|
||||
return HttpClient(Darwin) {
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
ignoreUnknownKeys = true
|
||||
isLenient = true
|
||||
})
|
||||
}
|
||||
install(DefaultRequest) {
|
||||
tokenManager.getAccessToken()?.let {
|
||||
header("Authorization", "Bearer $it")
|
||||
install(Auth) {
|
||||
bearer {
|
||||
loadTokens {
|
||||
val access = tokenManager.getAccessToken()
|
||||
val refresh = tokenManager.getRefreshToken()
|
||||
if (access != null && refresh != null) {
|
||||
BearerTokens(access, refresh)
|
||||
} else null
|
||||
}
|
||||
refreshTokens {
|
||||
Napier.d(">>>>> [NetworkEngine.ios.kt] Access token expired, auto request refresh token...")
|
||||
val newAccess = authApi?.refreshToken()
|
||||
if (newAccess != null) {
|
||||
BearerTokens(newAccess, tokenManager.getRefreshToken()!!)
|
||||
} else {
|
||||
tokenManager.clearTokens()
|
||||
tokenManager.triggerSessionExpired()
|
||||
throw ForceLogoutException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
install(HttpTimeout) { requestTimeoutMillis = 30_000 }
|
||||
@@ -46,30 +67,4 @@ actual fun createPlatformHttpClient(
|
||||
level = LogLevel.ALL // set LogLevel.NONE for release
|
||||
}
|
||||
}
|
||||
|
||||
if (authApi != null) {
|
||||
client.plugin(HttpSend).intercept { request ->
|
||||
// Skip interceptor for refresh token request to avoid recursion
|
||||
if (request.url.pathSegments.contains(ReferKeys.REFRESH_TOKEN)) {
|
||||
return@intercept execute(request)
|
||||
}
|
||||
|
||||
val originalCall = execute(request)
|
||||
if (originalCall.response.status == HttpStatusCode.Unauthorized) {
|
||||
Napier.d(">>>>> [NetworkEngine.ios.kt] Access token expired, auto request refresh token...")
|
||||
val newToken = authApi.refreshToken()
|
||||
if (newToken != null) {
|
||||
request.headers["Authorization"] = "Bearer $newToken"
|
||||
execute(request)
|
||||
} else {
|
||||
tokenManager.clearTokens()
|
||||
throw ForceLogoutException()
|
||||
}
|
||||
} else {
|
||||
originalCall
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user