#android #oauth #retrofit #retrofit2 #okhttp
#Android #oauth #модернизация #модернизация 2 #okhttp
Вопрос:
Когда срок действия токена доступа моего приложения истек, я использую токен обновления, чтобы получить новый токен доступа через класс аутентификации.
Мой код следует:
if (response.code() == 401) {
Log.d("refresh", "Access token expired")
val webservice: Webservice = RetrofitClient.makeRetrofitService().create(Webservice::class.java)
var refreshToken = PreferenceData.getUserLoggedInRefreshToken(App.GetContext()!!)
var map = generateRequestBody(mapOf("refreshToken" to refreshToken!!))
var refreshResponse = webservice.refreshToken(map).execute()
if (refreshResponse != null amp;amp; refreshResponse.code() == 200) {
Log.d("refresh", "New access token received")
var newToken = (refreshResponse.body() as UserLogin).token
var refreshToken = (refreshResponse.body() as UserLogin).refreshToken
PreferenceData.setUserLoggedInAccessToken(App.GetContext()!!, newToken)
PreferenceData.setUserLoggedInRefreshToken(App.GetContext()!!, refreshToken)
return response.request().newBuilder()
.header("Authorization", "Bearer $newToken")
.build();
}
}
Пока все хорошо.
Что я хочу сделать сейчас, так это то, что когда истечет срок действия моего токена обновления, я хотел бы перенаправить пользователя на экран входа в приложение. Но моя проблема в том, что когда я вызываю
var refreshResponse = webservice.refreshToken(map).execute()
сервер также возвращает 401. Итак, моя проблема в том, что я не могу определить, связано ли полученное мной 401 с истечением срока действия токена доступа или токена обновления. Каков наиболее подходящий способ решения этой проблемы?
Спасибо!
Ответ №1:
Вы можете взглянуть на реализацию AppAuth-Android.
-
Перед выполнением любого вызова вы можете проверить, что у вас все еще есть действительный токен доступа, получить время его истечения и сравнить его с результатом
clock.getCurrentTimeMillis()
. -
На всякий случай, если токен доступа недействителен по другим причинам (например, токен доступа может быть отозван вручную), вы можете использовать перехватчик Okhttp для реагирования на 401-е сообщения.
-
Если срок действия токена доступа истек или вы получили 401, вы можете попытаться обновить токен доступа с помощью токена обновления.
-
Если токен обновления больше недействителен,
/token
конечная точка вернет следующую ошибку:
HTTP / 1.1 400 Неверный запрос { «ошибка»:»invalid_request» }
- Если вы получаете эту ошибку, вы можете выйти из системы пользователя и отправить ему экран входа в приложение.
Надеюсь, это вам поможет.
Комментарии:
1. похоже, мне следует попросить сервер вернуть 400 неверных запросов, чтобы я мог определить, вызван ли сбой истечением токена доступа или токена обновления. Еще одна вещь, которую я узнал из вашего ответа, заключается в том, что мы должны сначала проверить действительность токена на стороне клиентов, прежде чем полагаться на сервер, возможно, для экономии использования api. Спасибо!
2. Да, все возможные ошибки определены в OAuth 2.0 RFC . Там вы можете видеть, что когда токен обновления недействителен, истек или отозван, сервер должен вернуть
400
иinvalid_grant
код ошибки. Что касается локальной проверки истечения срока действия, это избавляет вас от ненужного сетевого вызова.3. @DavidMiguel место, где в репозитории проверяется истечение срока действия токена доступа, эта логика может дать сбой — если пользователь изменит время Android?