Я использую Retrofit2 в качестве HTTP-клиента для Android.Приложение использует токен доступа и токен обновления для связи с серверной частью.
Сценарий 1. Истек срок доступа к токену, вызов API завершается неудачно с кодом ошибки 401, после чего я использую Authenticator для использования токена обновления для получения новой пары токенов доступа и токенов обновления ипродолжить с новым токеном доступа для неудавшегося вызова.Все это хорошо работает при стабильном подключении к Интернету
Сценарий 2: Теперь учтите, что Интернет не стабилен и продолжает падать и выключаться.Интернет есть, вызов API прерывается из-за истекшего токена доступа, приложение выполняет входящий вызов с обновлением токена, чтобы получить новую пару токена доступа и обновления токена.Но прежде, чем я получу успех 200 для входа в систему, интернет звонит.Теперь Интернет вернулся, и мое приложение снова запускает вызов API и получает 401, а затем использует токен обновления для запуска нового входа в систему.Проблема в том, что сервер обновил новые маркеры доступа и обновления, но приложение так и не получило его, когда интернет отключился.Из-за этого токен обновления, который у меня был, больше не действителен (так как новая пара уже создана в бэкэнде и очищена от старого)
Не знаете, как мне поступить с этим сценарием?Вот мой класс аутентификатора:
public class MyAuthenticator implements Authenticator {
Context context;
public MyAuthenticator(Context context) {
this.context = context;
}
@Nullable
@Override
public Request authenticate(Route route, Response response) throws IOException {
Retrofit client = new Retrofit.Builder()
.baseUrl(Manager.API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService service = client.create(ApiService.class);
SharedPreferenceManager sharedPreferenceManager = new SharedPreferenceManager(context);
String refreshToken = sharedPreferenceManager.getRefreshToken(context);
AuthRequest authRequest = new AuthRequest();
authRequest.grant_type = "refresh_token";
authRequest.refresh_token = refreshToken;
Call<authResponse> refreshTokenResult = service.refreshToken(authRequest);
retrofit2.Response accessTokenResponse = refreshTokenResult.execute();
//check if response equals 400 , mean empty response
if (accessTokenResponse.isSuccessful()) {
AuthResponse refreshResult = (AuthResponse) accessTokenResponse.body();
//save new access and refresh token
sharedPreferenceManager.writeLoginResponse(context, refreshResult);
// then create a new request and modify it accordingly using the new token
return response.request().newBuilder()
.header("Authorization", "Bearer " + refreshResult.access_token)
.build();
} else {
LoginActivity_.intent(context).flags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK).start();
return null;
}
}
}
Не уверен, что мне не хватает и как мне решить эту проблему.