在 Android 中的拦截器中进行另一个 API 调用是否有问题?
Is there a problem doing another API call inside interceptor in Android?
我在尝试刷新拦截器内的访问令牌时遇到问题。我读过最好使用 Authenticator 来解决这个问题,但我的 API 的工作方式是我得到一个 403 错误,用于未经授权的访问令牌(不是我的设计,但必须使用它)。
所以我试图调用 API 端点以在我的拦截器中获取新的访问令牌,但似乎第二个 API 调用创建了一个 OKHTTP 响应而不关闭它。
override fun intercept(chain: Interceptor.Chain?): Response {
var currentRequest = chain!!.request()
val currentRequestResponse = chain.proceed( currentRequest )
if ( currentRequestResponse.code() >= HTTP_ERROR_CODE && isNotLoginRequest( chain ) ) {
try {
// we check the response code, if there is 403 code we need to relog the user
// before executing the request
// try to reconnect the user with synchronous request
val userManager = UserManager.getInstance()
val clientId = getQueryParameter(UserService.CLIENT_ID_QUERY_KEY, currentRequest)
val redirectUri = getQueryParameter(UserService.REDIRECT_URI_QUERY_KEY, currentRequest)
val clientSecret = getQueryParameter(UserService.CLIENT_SECRET_QUERY_KEY, currentRequest)
// we get a new access token with a synchronous request
val accessToken = userManager.refreshToken(clientId, clientSecret, redirectUri)
currentRequest = rebuildRequestWithNewToken( accessToken, currentRequest )
return chain.proceed( currentRequest )
} catch (e: Throwable) {
e.printStackTrace()
}
}
return currentRequestResponse
}
我认为问题出在 userManager.refreshToken,即获取新访问令牌的 API 调用。
这是我收到的错误:
java.lang.IllegalStateException: 无法发起新的请求,因为之前的响应还未完成:请调用response.close()
您可以像这样在网络拦截器中调用刷新令牌
if (response.code() == 403) {
try {
val body = RequestBody.create(contentType, "")
val authRequest = request.newBuilder()
.setDefaultHeaders()
.addHeader("Authorization", "Your token")
.url(refreshtokenurl)
.post(body)
.build()
val tokenRefreshResponse = chain.proceed(authRequest)
if (tokenRefreshResponse.code() == 401 || tokenRefreshResponse.code() == 403) {
//error in refreshing token
} else if (tokenRefreshResponse.code() == 200) {
//save the new token and refresh token in preference and continue with the earlier request
currentRequestResponse = chain.proceed(currentRequest.newBuilder()
.setDefaultHeaders()
.addHeader(your header)
.build())
}
} catch (e: Exception) {
}
}
今天遇到同样的错误“无法发出新的请求,因为之前的响应仍处于打开状态”。
人们说在最新的 Retrofit 版本中,我们应该使用 initialResponse.close() 方法关闭初始响应。
https://medium.com/@113408/this-is-a-nice-implementation-of-the-authinterceptor-however-on-newer-version-of-okhttp-retrofit-9cf20477e2af
我在尝试刷新拦截器内的访问令牌时遇到问题。我读过最好使用 Authenticator 来解决这个问题,但我的 API 的工作方式是我得到一个 403 错误,用于未经授权的访问令牌(不是我的设计,但必须使用它)。
所以我试图调用 API 端点以在我的拦截器中获取新的访问令牌,但似乎第二个 API 调用创建了一个 OKHTTP 响应而不关闭它。
override fun intercept(chain: Interceptor.Chain?): Response {
var currentRequest = chain!!.request()
val currentRequestResponse = chain.proceed( currentRequest )
if ( currentRequestResponse.code() >= HTTP_ERROR_CODE && isNotLoginRequest( chain ) ) {
try {
// we check the response code, if there is 403 code we need to relog the user
// before executing the request
// try to reconnect the user with synchronous request
val userManager = UserManager.getInstance()
val clientId = getQueryParameter(UserService.CLIENT_ID_QUERY_KEY, currentRequest)
val redirectUri = getQueryParameter(UserService.REDIRECT_URI_QUERY_KEY, currentRequest)
val clientSecret = getQueryParameter(UserService.CLIENT_SECRET_QUERY_KEY, currentRequest)
// we get a new access token with a synchronous request
val accessToken = userManager.refreshToken(clientId, clientSecret, redirectUri)
currentRequest = rebuildRequestWithNewToken( accessToken, currentRequest )
return chain.proceed( currentRequest )
} catch (e: Throwable) {
e.printStackTrace()
}
}
return currentRequestResponse
}
我认为问题出在 userManager.refreshToken,即获取新访问令牌的 API 调用。
这是我收到的错误:
java.lang.IllegalStateException: 无法发起新的请求,因为之前的响应还未完成:请调用response.close()
您可以像这样在网络拦截器中调用刷新令牌
if (response.code() == 403) {
try {
val body = RequestBody.create(contentType, "")
val authRequest = request.newBuilder()
.setDefaultHeaders()
.addHeader("Authorization", "Your token")
.url(refreshtokenurl)
.post(body)
.build()
val tokenRefreshResponse = chain.proceed(authRequest)
if (tokenRefreshResponse.code() == 401 || tokenRefreshResponse.code() == 403) {
//error in refreshing token
} else if (tokenRefreshResponse.code() == 200) {
//save the new token and refresh token in preference and continue with the earlier request
currentRequestResponse = chain.proceed(currentRequest.newBuilder()
.setDefaultHeaders()
.addHeader(your header)
.build())
}
} catch (e: Exception) {
}
}
今天遇到同样的错误“无法发出新的请求,因为之前的响应仍处于打开状态”。
人们说在最新的 Retrofit 版本中,我们应该使用 initialResponse.close() 方法关闭初始响应。 https://medium.com/@113408/this-is-a-nice-implementation-of-the-authinterceptor-however-on-newer-version-of-okhttp-retrofit-9cf20477e2af