Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用okhttp身份验证程序一次刷新多个请求的令牌_Android_Kotlin_Oauth_Retrofit_Okhttp - Fatal编程技术网

Android 如何使用okhttp身份验证程序一次刷新多个请求的令牌

Android 如何使用okhttp身份验证程序一次刷新多个请求的令牌,android,kotlin,oauth,retrofit,okhttp,Android,Kotlin,Oauth,Retrofit,Okhttp,我在我的项目中使用网络改造。问题是我必须从我的第一个活动中调用2个请求。它工作正常,但当访问令牌到期时,它必须刷新令牌。我已经使用okhttp验证器实现了一个调用。但它多次调用,并且此错误显示太多后续请求21 编辑 我更新了TokenAuthenticator类并添加了synchronized()。但是它是从返回的,如果(originalRequest.header(“Authorization”)!=null)返回null。我正在遵循这个答案 如果我正在删除If(originalRequest

我在我的项目中使用网络改造。问题是我必须从我的第一个活动中调用2个请求。它工作正常,但当访问令牌到期时,它必须刷新令牌。我已经使用okhttp验证器实现了一个调用。但它多次调用,并且此错误显示太多后续请求21

编辑 我更新了TokenAuthenticator类并添加了synchronized()。但是它是从
返回的,如果(originalRequest.header(“Authorization”)!=null)返回null
。我正在遵循这个答案

如果我正在删除
If(originalRequest.header(“Authorization”)!=null)返回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
}
}

在您的
令牌验证器中尝试以下操作:

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
}

不,它不起作用。它现在显示身份验证错误。401来自主请求的身份验证错误。您的答案是否适用于同时发送两个请求?它将只调用1次刷新令牌,然后在令牌刷新后再次调用这两个api?根据我的回答,当主请求返回401时,令牌将同步刷新,主请求将使用新令牌再次调用。但我同时从我的活动中调用了2个请求,因此两个都在调用Athenicator以获取刷新令牌。我需要一些东西,比如它将停止第二个请求,并在令牌刷新后再次调用这两个。请尝试以下操作:您是否能够修复此问题?
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
}