Цепочка перехватчиков OkHttp разорвана при получении токена

У меня есть перехватчик OkHttp, который должен запрашивать токен, когда запрос получает ошибку HTTP 401. Теперь запрос на вход в службу выполняется, но затем цепочка прерывается, и исходный запрос не повторяется. Вот метод перехвата моего перехватчика:

override fun intercept(chain: Interceptor.Chain): Response {
        logger.d("AuthenticationServiceHolder $authenticationServiceHolder")

        val originalRequest = chain.request()
        logger.d("Intercepting call to ${originalRequest.method()} ${originalRequest.url()}")

        val response: Response = chain.proceed(originalRequest)
        val successful = response.isSuccessful
        val code = response.code()
        logger.d("Response successful: $successful - code: $code")

        if (!successful && code == HttpURLConnection.HTTP_UNAUTHORIZED) {
            logger.d("Token is $token")

            val deviceUuid = deviceIdentificationManager.deviceUuid().blockingGet()
            logger.d("Device uuid $deviceUuid")
            if (deviceUuid != null) {
                val authenticationService = authenticationServiceHolder.get()
                if (authenticationService != null) {
                    token = reLogin(authenticationService, deviceUuid)
                    if (token != null) {
                        val headersBuilder = originalRequest.headers().newBuilder()
                        headersBuilder.removeAll(AUTHORIZATION_HEADER)
                        headersBuilder.add(AUTHORIZATION_HEADER, token!!)

                        val requestBuilder = originalRequest.newBuilder()
                        val request = requestBuilder.headers(headersBuilder.build()).build()
                        return chain.proceed(request)
                    } else {
                        logger.e("Token was not retrieved")
                    }
                } else {
                    logger.e("Authentication service is null!")
                }
            }
        }
        return response
}

Метод reLogin():

private fun reLogin(authenticationService: AuthenticationService, deviceUuid: UUID): String? {
        logger.d("reLogin() - authenticationService $authenticationService")
        val blockingGet = authenticationService?.login(LoginRequest(deviceUuid, clock.currentTime()))?.blockingGet()
        logger.d("reLogin() - response $blockingGet")
        val response = blockingGet ?: return null
        logger.d("reLogin() - token ${response.token}")
        return response.token
}

НОВЫЙ: Как говорит Митеш Мачхойя, я пробовал с двумя разными экземплярами модернизации, у одного есть клиент okhttp с перехватчиком, а у другого его нет. И теперь вызов входа в систему не перехватывается, но выполнение Interceptor прерывается, я имею в виду трассировку журнала этого класса:

 - AuthenticationServiceHolder XXXmypackageXXX.AuthenticationServiceHolder... 
 - Intercepting call to GET XXXmyInterceptedCallXXX 
 - Response successful: false - code: 401 
 - Token is null 
 - Device uuid XXX 
 - reLogin() - authenticationService retrofit2.Retrofit$1@a5c0a25 

И ничего больше. Я имею в виду, что reLogin() - response..... не печатается. Я уверен, что вызов входа в систему работает, потому что я вижу ответ на вход в журнал okhttp.

С okhttp Authenticator проще работать для обработки 401 и повторных попыток.

laalto 14.06.2019 12:52
0
1
1 117
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Сделайте запрос reLogin с другим httpClient без подключения перехватчика, тогда он будет работать так, как вы ожидали.

если вы делаете запрос reLogin с тем же httpClient, то он будет проходить через перехватчик и каждый раз переопределять запрос, поэтому попробуйте сделать запрос, используя другой httpClient

Я только что попробовал, и теперь вызов входа в систему не перехватывается, но выполнение Interceptor прерывается, я имею в виду, что трассировка журнала этого класса: : false - код: 401 - Токен нулевой - Устройство uuid XXX - reLogin() - authenticationService retrofit2.Retrofit$1@a5c0a25 И ничего больше. Должно быть reLogin() - response..... Я уверен, что вызов входа в систему работает, потому что я вижу ответ с журналом okhttp

SergiBC 14.06.2019 15:04

не делайте вызов с блокировкой, сделайте асинхронный вызов и посмотрите, что происходит

Mitesh Machhoya 14.06.2019 15:13

Насколько я знаю, вызовы внутри перехватчиков должны быть синхронными... если нет, то как я могу добавить токен в заголовок?

SergiBC 14.06.2019 15:24
Ответ принят как подходящий

Вставленный код работает хорошо, запрос на вход работает, но ответ на вход был изменен на стороне сервера, а десериализация привела к сбою и разорвала цепочку.

Другие вопросы по теме