sad*_*dat 5 android okhttp retrofit2 kotlin-coroutines
我正在尝试使用身份验证器来处理 401 响应。我所做的是
fun provideAccessTokenAuthenticator(
mainApiServiceHolder: MainApiServiceHolder,
preferences: SharedPreferences
) = object : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
val accessToken = preferences.getString(ACCESS_TOKEN, null)
if (!isRequestWithAccessToken(response) || accessToken == null) {
return null
}
synchronized(this) {
val newAccessToken = preferences.getString(ACCESS_TOKEN, null)!!
// Access token is refreshed in another thread.
if (accessToken != newAccessToken) {
return newRequestWithAccessToken(response.request, newAccessToken)
}
// Need to refresh an access token
val refreshTokenResponse = runBlocking {
Log.d("zzzzzzzzzz", "refresh token is running")
mainApiServiceHolder.mainApiService?.refreshToken(
"refresh_token",
preferences.getString(REFRESH_TOKEN, null)!!,
AuthRepository.CLIENT_ID,
AuthRepository.CLIENT_SECRET
)
}
Log.d("zzzzzzzzzz", refreshTokenResponse?.body()?.access_token!!)
return if (refreshTokenResponse?.isSuccessful!!) {
Log.d("zzzzzzzzzz", "refresh token is successful")
newRequestWithAccessToken(
response.request,
refreshTokenResponse.body()?.access_token!!
)
} else {
Log.d("zzzzzzzzzz", "refresh token is unsuccessful")
response.request.newBuilder().header("Content-Type", "application/json").build()
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当有 401 响应时它会被调用。刷新令牌调用也会被触发(来自 Log)。但是,它永远不会在 refreshTokenResponse 中获得结果,之后没有任何反应。我认为这是使用 runBlock 的错误方式。api是
@FormUrlEncoded
@POST("/api/auth/token/")
suspend fun refreshToken(
@Field("grant_type") grant_type: String,
@Field("refresh_token") refresh_token: String,
@Field("client_id") client_id: String,
@Field("client_secret") client_secret: String
): Response<LoginResponse>
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激。谢谢
在 Retrofit API 中,考虑用同步Call替换异步 runBlocking{} 挂起乐趣。我最幸运的是避免在 Authenticator 中使用协程。
我遇到了同样的问题。令牌请求直接进入了一个黑洞。该应用程序冻结。该请求再也没有出现过。没有错误,没有什么。
但是在应用程序的其他任何地方,暂停的乐趣都恢复得很好。从 ViewModels 到 WorkManager,它每次都有效。但从身份验证器,从来没有。身份验证器出了什么问题?Authenticator 有什么特别之处让它如此行事?
然后我用一个简单的Call替换了 runBlocking{} 协程。这一次,请求回来了,令牌没有大惊小怪地到达。
我让 API 工作的方式如下所示:
@FormUrlEncoded
@POST("token")
fun refreshTokenSync(
@Field("refresh_token") refreshToken: String,
): Call<RefreshMyTokenResponse>
Run Code Online (Sandbox Code Playgroud)
然后,在身份验证器中:
val call = API.refreshTokenSync(refreshToken)
val response = call.execute().body()
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助遇到同样问题的其他人。您可能会收到来自 Android Studio 的警告,指出这是一个不当的阻塞调用。不要付钱,没关系。
| 归档时间: |
|
| 查看次数: |
1312 次 |
| 最近记录: |