Auto-refresh auth token on 401

This commit is contained in:
androidlover5842
2026-01-28 04:50:20 +05:30
parent d8a40e4c9a
commit d2d60b5074
3 changed files with 21 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
package com.android.trisolarispms.data.api
import com.google.firebase.auth.FirebaseAuth
import okhttp3.Authenticator
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
@@ -18,7 +19,7 @@ object ApiClient {
val authInterceptor = Interceptor { chain ->
val original = chain.request()
val token = try {
kotlinx.coroutines.runBlocking { tokenProvider.token() }
kotlinx.coroutines.runBlocking { tokenProvider.token(forceRefresh = false) }
} catch (e: Exception) {
null
}
@@ -32,12 +33,28 @@ object ApiClient {
chain.proceed(request)
}
val authenticator = Authenticator { _, response ->
if (response.code != 401) return@Authenticator null
if (response.request.header("X-Auth-Retry") == "true") return@Authenticator null
val newToken = try {
kotlinx.coroutines.runBlocking { tokenProvider.token(forceRefresh = true) }
} catch (e: Exception) {
null
}
if (newToken.isNullOrBlank()) return@Authenticator null
response.request.newBuilder()
.header("Authorization", "Bearer $newToken")
.header("X-Auth-Retry", "true")
.build()
}
val logging = HttpLoggingInterceptor().apply {
level = if (enableLogging) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
}
val client = OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.authenticator(authenticator)
.addInterceptor(logging)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)

View File

@@ -1,5 +1,5 @@
package com.android.trisolarispms.data.api
interface AuthTokenProvider {
suspend fun token(): String?
suspend fun token(forceRefresh: Boolean = false): String?
}

View File

@@ -6,8 +6,8 @@ import kotlinx.coroutines.tasks.await
class FirebaseAuthTokenProvider(
private val auth: FirebaseAuth
) : AuthTokenProvider {
override suspend fun token(): String? {
override suspend fun token(forceRefresh: Boolean): String? {
val user = auth.currentUser ?: return null
return user.getIdToken(false).await().token
return user.getIdToken(forceRefresh).await().token
}
}