如何使用具有多个请求的okhttp身份验证器刷新令牌

问题描述 投票:0回答:1

我正在为我的项目中的网络使用改造。问题是我必须在第一个活动中调用2个请求。它工作正常,但是当访问令牌过期时,它必须刷新令牌。我已经使用okhttp Authenticator实现了呼叫。但是它多次校准,并且此错误也显示too many followup request 21

这是我的Authenticator类

class TokenAuthenticator : Authenticator {

private val refreshTokenGrandType = "refresh_token"
private var access_token : String? = null
private var is_refreshing : Boolean = false

override fun authenticate(route: Route, response: Response): Request? {
    val token = SharedPreferenceManager(MainApplication.applicationContext()).getToken()    // Old Access Token
    if (response.code() == 401){
        if (!is_refreshing){
            is_refreshing = true
            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()
                }

                override fun onResponse(call: Call<Token>, response: retrofit2.Response<Token>) {
                    if (response.isSuccessful){
                        val body = response.body()
                        access_token = body!!.access_token
                        val refresh_token = body.refresh_token

                        SharedPreferenceManager(MainApplication.applicationContext()).accessToken(access_token!!,refresh_token)    // Saving New Access Token

                        is_refreshing = false
                    }else {
                        val error = response.errorBody()
                        is_refreshing = false
                    }
                }
            })
        }
    }

    if (!token.equals(access_token)) {     //Checking old access token and new access token are different or not
        if (SharedPreferenceManager(MainApplication.applicationContext()).getToken() != null) {
            return response
                .request()
                .newBuilder()
                .header(
                    "Authorization",
                    "Bearer ${SharedPreferenceManager(MainApplication.applicationContext()).getToken()}"
                )
                .build()
        } else return null
    }else return null
}
}

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!!
    }
 }
android kotlin oauth retrofit okhttp
1个回答
0
投票

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
}
© www.soinside.com 2019 - 2024. All rights reserved.