Проблемы с механизмом обновления токена при модернизации с помощью OkHttpAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Проблемы с механизмом обновления токена при модернизации с помощью OkHttp

Сообщение Anonymous »

У меня возникла проблема с механизмом обновления токена в моем приложении Android с использованием Retrofit и OkHttp. Следующий код предназначен для перехвата запросов API, добавления токена доступа в заголовки запросов и обновления токена в случае получения ответа 401 Unauthorized. Однако похоже, что запрос токена обновления не работает должным образом.

Код: Выделить всё

class ApiClient {
companion object {
private const val BASE_URL = "..." // API base URL
private var INSTANCE: Retrofit? = null

fun getInstance(context: Context): Retrofit {
if (INSTANCE == null) {
val builder = OkHttpClient.Builder()

val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
builder.addInterceptor(logging)
builder.addInterceptor(TokenInterceptor(context))

INSTANCE = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return INSTANCE!!
}
}
}

class TokenInterceptor(private val context: Context) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val accessToken = PreferenceUtil(context).getAccessToken()
Log.d("ApiClient", "Current token: $accessToken")

// Add access token to header if it exists
val requestWithToken = if (accessToken != null) {
originalRequest.newBuilder()
.header("Authorization", "Bearer $accessToken")
.build()
} else {
originalRequest
}

// Send request
var originalResponse = chain.proceed(requestWithToken)

if (originalResponse.code == 401) {
// Refresh token request
Log.e("ApiClient", "Token expired error, ${originalResponse.code}")

val refreshToken = PreferenceUtil(context).getRefreshToken()
Log.d("ApiClient", "Refresh token: $refreshToken")

if (refreshToken != null) {
Log.d("ApiClient", "Refresh token exists!")

// Asynchronous task to request a new access token
val newAccessToken = runBlocking {
reissueToken(refreshToken)
Log.d("ApiClient", "Why is this not working?")
}

newAccessToken?.let {
Log.d("ApiClient", "Replacing with new refresh token!")

val newRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer $it")
.build()

originalResponse = chain.proceed(newRequest)
}
}
}

return originalResponse
}

private suspend fun reissueToken(refreshToken: String): String? {
return withContext(Dispatchers.IO) {
val apiService = ApiClient.getInstance(context).create(LogInService::class.java)
val response = apiService.reissueToken(refreshToken)
Log.d("ApiClient", "Receiving new response: ${response}")

if (response.isSuccessful) {
Log.d("ApiClient", "Response successful")

response.body()?.let { tokenResponse ->
Log.d("ApiClient", "Token successfully renewed")
PreferenceUtil(context).setAccessToken(tokenResponse.accessToken)
PreferenceUtil(context).setRefreshToken(tokenResponse.refreshToken)
return@withContext tokenResponse.accessToken
}
} else {
Log.d("ApiClient", "Response failed...")
null
}
}
}
}

Вот соответствующие части моего кода:
  • ApiClient: инициализирует модернизацию с помощью OkHttpClient и добавляет TokenInterceptor.< /li>
    TokenInterceptor: перехватывает запросы и проверяет токен доступа. Если он получает ответ 401, он пытается обновить токен.
Журналы:
"Текущий токен: $accessToken"
"Ошибка срока действия токена, 401"
"Обновить токен: $refreshToken"
"Обновить токен существует!"

Подробнее здесь: https://stackoverflow.com/questions/791 ... ith-okhttp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»