Я использую модернизацию для сети в моем проекте. Проблема в том, что мне нужно позвонить 2 запроса из моей первой деятельности. Он работает нормально, но когда токен доступа истекает, он должен обновить токен. Я реализовал вызов, используя okhttp Authenticator. Но он вызывает несколько раз, и эта ошибка также показывает too many followup request 21
EDIT Я обновил класс TokenAuthenticator и добавил synchronized (). но он возвращается с if (originalRequest.header("Authorization") != null) return null
. Я слежу за этим ответом https://stackoverflow.com/a/52513122/10243953
Если я удаляю if (originalRequest.header("Authorization") != null) return null
эту строку, то она работает, но в отчете журнала я вижу, что она вызывает запрос на обновление токена несколько раз. Как я могу избежать этого многократных вызовов?
Это мой класс Аутентификатора
class TokenAuthenticator : Authenticator {
private val refreshTokenGrandType = "refresh_token"
private var oldToken: String? = null
private var newToken: String? = null
override fun authenticate(route: Route?, response: Response?): Request? {
oldToken = SharedPreferenceManager(MainApplication.applicationContext()).getToken()
if (response == null) return null
val originalRequest = response.request()
if (originalRequest.header("Authorization") != null) return null
if(!isTokenSaved()){
synchronized(this) {
RetrofitClient.client.create(Auth::class.java).refresh_token(
SharedPreferenceManager(MainApplication.applicationContext()).getRefreshToken()!!,
refreshTokenGrandType
).enqueue(object : Callback<Token> {
override fun onFailure(call: Call<Token>, t: Throwable) {
Toast.makeText(
MainApplication.applicationContext(),
t.message,
Toast.LENGTH_SHORT
).show()
Log.d("TokenAuth", t.message!!)
}
override fun onResponse(
call: Call<Token>,
response: retrofit2.Response<Token>
) {
if (response.isSuccessful) {
val body = response.body()
newToken = body!!.access_token
val refresh_token = body.refresh_token
SharedPreferenceManager(MainApplication.applicationContext()).accessToken(
newToken!!,
refresh_token
)
} else {
val error = response.errorBody()
Log.d("TokenAuthRes", error!!.string())
}
}
})
}
}
return originalRequest
.newBuilder()
.header(
"Authorization",
"Bearer ${SharedPreferenceManager(MainApplication.applicationContext()).getToken()}"
)
.build()
}
fun isTokenSaved() : Boolean{
if (newToken == null) return false
if (oldToken.equals(newToken)) return false
else return true
}
}
Модифицированный клиент
object RetrofitClient {
private lateinit var interceptor : Interceptor
private lateinit var okHttpClient: OkHttpClient
private var retrofit : Retrofit? = null
val client : Retrofit
get(){
val context : Context = MainApplication.applicationContext()
interceptor = Interceptor { chain ->
val url = chain.request()
.url()
.newBuilder()
.build()
val request = chain.request()
.newBuilder()
.addHeader("Authorization","Bearer ${SharedPreferenceManager(context).getToken()}")
.url(url)
.build()
return@Interceptor chain.proceed(request)
}
okHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(NoInternetInterception(context))
.authenticator(TokenAuthenticator())
.connectTimeout(1, TimeUnit.MINUTES)
.build()
if (retrofit == null){
retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(const.URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit!!
}
}