使用 okhttp 进行身份验证时,此处不允许使用 return

return is not allowed here when authenticating using okhttp

我正在尝试实施刷新令牌流程。基本上我有一个在一小时后过期的访问令牌,以及一个我发送到服务器以获得新访问令牌的刷新令牌。

我使用 okhttp 作为我的 http 客户端,它内置了对身份验证的支持,但问题是在身份验证方法中我必须 return 一个带有新访问令牌的 Request 对象。 为此,首先我必须等待 api 调用以使用我提供的刷新令牌检索新的访问令牌,如您所知,此过程需要一段时间才能完成。

我的问题是如何等待结果的到来,然后 return 我的 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
}
}

旁注:

  1. 使用 RX 时,我无法 return 来自 doOnSuccess 内部的请求对象。
  2. 在第一次协程尝试中,使用 job.join() 要求 authenticate 方法是一个挂起函数,我不允许更改它。
  3. 在第二次协程尝试中,它似乎没问题,但它不会阻止 UI 线程这样做吗?或者因为整个过程发生在 UI 线程之外,应用程序不会冻结!?

谢谢。

事实证明,由于我们已经在后台线程中,我们可以使用同步任务并等待响应。

override fun authenticate(route: Route?, response: Response): Request? {

    //With RX
    val newToken = getTokenFromServer().blockingGet()
    return newToken

    //Or a retrofit call object
    val newToken = getTokenFromServer().execute()
    return newToken
}