android - 在 Android 的拦截器中执行另一个 API 调用是否有问题?

标签 android kotlin retrofit2 okhttp interceptor

我有一个问题,我试图在拦截器中刷新访问 token 。我已经读过最好使用 Authenticator 来解决这个问题,但我的 API 的工作方式是我收到未经授权的访问 token 的 403 错误(不是我的设计,但必须使用它)。

所以我试图调用 API 端点以在我的拦截器中获取新的访问 token ,但似乎第二个 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 这是获取新访问 token 的 API 调用。

这是我收到的错误:

java.lang.IllegalStateException:无法发出新请求,因为之前的响应仍然打开:请调用 response.close()

最佳答案

您可以像这样在网络拦截器中进行刷新 token 调用

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) {

            }

        }

关于android - 在 Android 的拦截器中执行另一个 API 调用是否有问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57294403/

相关文章:

Android onKeyDown 没有捕捉到 Dpad 中心并输入按键

android - 在 Android Studio 中为 android 应用程序设置开发和生产环境

java - 无法从主要 Activity 转到另一个 Activity ,应用程序崩溃

android - [Android] [改造]使用拦截器调用不同的API

java - 刷新访问 token Retrofit2 + RXJava2

java - 当 setMaxFileSize() 和 setMaxDuration() 组合使用时 MediaRecorder 服务器崩溃

java - 如何在 Android 上将相机方向锁定为纵向

android - 使用Appium对Android应用进行黑测

intellij-idea - 为什么 smart cast 如此突出?

php - 如何在android TextView 上查看php脚本的结果