Auto-refresh auth token on 401
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.android.trisolarispms.data.api
|
||||
|
||||
interface AuthTokenProvider {
|
||||
suspend fun token(): String?
|
||||
suspend fun token(forceRefresh: Boolean = false): String?
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user