我正试图向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之前等待令牌加载。