如何将带有Firebase ID Token的改造服务注入kodein



我正试图向kodien注入一项改造服务。API服务使用Firebase Auth令牌进行身份验证。因此,我必须通过从Firebase auth.getInstance((.getIdToken((获取令牌来将请求标头中的id令牌作为基本身份验证进行传递,该令牌在Task回调中提供令牌。现在我面临的问题是,我必须将令牌传递给http客户端请求拦截器。我不知道怎么做。

我已经看了一些例子Kotlin推论的解决方案。但我是Kotlin Coroutines的新手,没能学到很多东西。

这是我的kodien物件。

override val kodein by Kodein.lazy {
import(androidXModule(this@App))
bind() from singleton { FirebaseDatabase.getInstance() }
bind<ApiService>() from singleton {  RetrofitFactory.makeApiService() }
}

我的改装工厂。

object RetrofitFactory {
fun makeApiService(): ApiService {
FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnCompleteListener {
if (it.isSuccessful){
// HERE IS THE TOKEN
val token = it.result?.token
}
}
val client = OkHttpClient.Builder()
.addInterceptor {
val request = it.request().newBuilder()
.addHeader("authorization", "*** PASS TOKEN HERE ***")
.build()
it.proceed(request)
}
.build()
return Retrofit.Builder()
.client(client)
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}

我可能完全错了,或者有更好的方法。

感谢您的帮助。

提前谢谢。

我找到了一个解决方案。

创建一个类似下面的TokenProvider

class TokenProvider {
private var token: String = ""
fun get() = token
fun load() {
getToken {
token = it
}
}
private fun getToken(callback: (String) -> Unit) {
FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnCompleteListener {
if (it.isSuccessful){
callback(it.result?.token!!)
}
}
}
} 

在kodein 中注入TokenProvider

override val kodein by Kodein.lazy {
import(androidXModule(this@App))
bind() from singleton { TokenProvider() }
bind<ApiService>() with singleton { RetrofitFactory.makeApiService(instance()) }
}

TokenProvider传递给makeServiceApi作为参数并使用它

object RetrofitFactory {
fun makeApiService(tokenProvider: TokenProvider): ApiService {
val token = tokenProvider.get()
val client = OkHttpClient.Builder()
.addInterceptor {
val request = it.request()
.newBuilder()
.addHeader("authorization", "Bearer $token")
.build()
it.proceed(request)
}
.build()
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}

最后,在应用程序onCreate中加载令牌

override fun onCreate() {
super.onCreate()
val tokenProvider by instance<TokenProvider>()
tokenProvider.load()
}

这个解决方案存在一个边缘情况。如果你在应用程序加载后立即调用Api。到那时,如果没有加载firebase令牌。然后Api调用将失败。

这对我有效,因为我不会在应用程序加载时调用Api。仍在寻找能够解决这种边缘情况的解决方案。一种解决方法是在调用Api之前等待令牌加载。

最新更新