【发布时间】:2021-09-01 23:06:23
【问题描述】:
我正在尝试实现刷新令牌过程。基本上我有一个会在一小时内过期的访问令牌,以及一个我发送到服务器以获取新访问令牌的刷新令牌。
我使用 okhttp 作为我的 http 客户端,它内置了对身份验证的支持,但问题是在身份验证方法中,我必须返回一个带有新访问令牌的 Request 对象。 为此,首先我必须等待 api 调用以使用我提供的刷新令牌检索新的访问令牌,如您所知,此过程需要一段时间才能完成。
我的问题是如何等待结果到来,然后返回我的 Request 对象?
class TokenAuthenticator : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
//With RX
val newToken = getTokenFromServer()?.doOnSuccess {
return response.request().newBuilder().url("URL").addHeader("token", it.result?.token)
.build()
}
//First coroutine attempt
val job = runblocking { launch { getTokenFromServer() } }
job.join()
//... create request
return request
//Second coroutine attempt
val request = runBlocking {
val newToken = getTokenFromServer()
//... create new request object here using newToken
return@runBlocking request
}
return request
}
fun getTokenFromServer(): Single<ApiResponse>? {
//... gets data from server and returns the result
return newToken
}
}
旁注:
- 使用 RX 时,我无法从 doOnSuccess 内部返回请求对象。
- 在第一次协程尝试中,使用 job.join() 需要 authenticate 方法是一个挂起函数,并且我不允许更改它。
- 在第二次协程尝试中似乎没问题,但它不会阻止 UI 线程这样做吗?还是因为整个过程都发生在 UI 线程之外,所以应用不会冻结!?
谢谢。
【问题讨论】:
-
我认为您不应该在身份验证器中放置任何异步代码。您只需将整个调用(您为其设置身份验证器的调用)包装为 RxJava 类型,就可以了。 (使用改造 + 改造 RxJava 适配器)
-
你能解释一下吗?包装整个通话是什么意思?
标签: android kotlin authentication okhttp refresh-token