У меня есть перехватчик 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.
Сделайте запрос reLogin с другим httpClient без подключения перехватчика, тогда он будет работать так, как вы ожидали.
если вы делаете запрос reLogin с тем же httpClient, то он будет проходить через перехватчик и каждый раз переопределять запрос, поэтому попробуйте сделать запрос, используя другой httpClient
Я только что попробовал, и теперь вызов входа в систему не перехватывается, но выполнение Interceptor прерывается, я имею в виду, что трассировка журнала этого класса: : false - код: 401 - Токен нулевой - Устройство uuid XXX - reLogin() - authenticationService retrofit2.Retrofit$1@a5c0a25 И ничего больше. Должно быть reLogin() - response..... Я уверен, что вызов входа в систему работает, потому что я вижу ответ с журналом okhttp
не делайте вызов с блокировкой, сделайте асинхронный вызов и посмотрите, что происходит
Насколько я знаю, вызовы внутри перехватчиков должны быть синхронными... если нет, то как я могу добавить токен в заголовок?
Вставленный код работает хорошо, запрос на вход работает, но ответ на вход был изменен на стороне сервера, а десериализация привела к сбою и разорвала цепочку.
С okhttp Authenticator проще работать для обработки 401 и повторных попыток.