如何将带有 Firebase ID 令牌的改造服务注入 kodein
How to inject retrofit service with Firebase ID Token into kodein
我正在尝试注入 retrofit service into kodien。 API 服务使用 Firebase Auth 令牌进行身份验证。因此,我必须通过从 Firebase Auth.getInstance().getIdToken() 获取令牌,将请求 header 中的 id 令牌作为基本身份验证传递给任务回调中的令牌。现在我面临的问题是我必须将令牌传递给 http 客户端请求拦截器。我不知道该怎么做。
我已经查看了一些示例 Kotlin Coroutines 以寻求解决方案。但我是 Kotlin Coroutines 的新手,并不能学到太多东西。
这是我的琴object。
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.
之前等待令牌加载
我正在尝试注入 retrofit service into kodien。 API 服务使用 Firebase Auth 令牌进行身份验证。因此,我必须通过从 Firebase Auth.getInstance().getIdToken() 获取令牌,将请求 header 中的 id 令牌作为基本身份验证传递给任务回调中的令牌。现在我面临的问题是我必须将令牌传递给 http 客户端请求拦截器。我不知道该怎么做。
我已经查看了一些示例 Kotlin Coroutines 以寻求解决方案。但我是 Kotlin Coroutines 的新手,并不能学到太多东西。
这是我的琴object。
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.
之前等待令牌加载