[英]How to refresh token using okhttp authenticator with multiple request at a time
I am using retrofit for networking in my project.我在我的项目中使用 retrofit 进行联网。 The problem is I have to call 2 requests from my first activity.
问题是我必须从我的第一个活动中调用 2 个请求。 It works fine but when the access token expires it has to refresh token.
它工作正常,但是当访问令牌过期时,它必须刷新令牌。 I have implemented a call using okhttp Authenticator.
我已经使用 okhttp Authenticator 实现了一个调用。 But it is calling multiple times and this error is showing too
too many followup request 21
但它多次调用,这个错误显示太多
too many followup request 21
EDIT I updated TokenAuthenticator class and added synchronized().编辑我更新了 TokenAuthenticator class 并添加了同步()。 but it is returning from
if (originalRequest.header("Authorization") != null) return null
.但它是从
if (originalRequest.header("Authorization") != null) return null
。 I am following this answer https://stackoverflow.com/a/52513122/10243953我正在关注这个答案https://stackoverflow.com/a/52513122/10243953
If i am removing if (originalRequest.header("Authorization") != null) return null
this line then its working but in log report i see its calling for refresh token multiple times.如果我要删除
if (originalRequest.header("Authorization") != null) return null
这一行,那么它可以工作,但在日志报告中我看到它多次调用刷新令牌。 How can i avoid this multiple time calls?我怎样才能避免这种多次通话?
This is my Authenticator class这是我的验证器 class
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
}
}
Retrofit client Retrofit客户端
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!!
}
}
Try this in your TokenAuthenticator
:在你的
TokenAuthenticator
中试试这个:
override fun authenticate(route: Route, response: Response): Request? {
val call = RetrofitClient.client.create(Auth::class.java).refresh_token(SharedPreferenceManager(MainApplication.applicationContext()).getRefreshToken()!!,refreshTokenGrandType)
val refreshResponse = call.execute()
if (refreshResponse.isSuccessful()) {
//Save your new token
return response
.request()
.newBuilder()
.header(
"Authorization",
"Bearer ${SharedPreferenceManager(MainApplication.applicationContext()).getToken()}"
)
.build()
} else return null
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.