Этот подход всегда работал при обновлении token
.То есть при каждом запросе, если я получил error 401
, оператор retryWhen()
вызвал его обновление токена.
Вот код:
private Observable<TokenModel> refreshAccessToken() {
Map<String, String> requestBody = new HashMap<>();
requestBody.put(Constants.EMAIL_KEY, Constants.API_EMAIL);
requestBody.put(Constants.PASSWORD_KEY, Constants.API_PASSWORD);
return RetrofitHelper.getApiService().getAccessToken(requestBody)
.subscribeOn(Schedulers.io())
.doOnNext((AccessToken refreshedToken) -> {
PreferencesHelper.putAccessToken(mContext, refreshedToken);
});
}
public Function<Observable<Throwable>, ObservableSource<?>> isUnauthorized (){
return throwableObservable -> throwableObservable.flatMap((Function<Throwable, ObservableSource<?>>) (Throwable throwable) -> {
if (throwable instanceof HttpException) {
HttpException httpException = (HttpException) throwable;
if (httpException.code() == 401) {
return refreshAccessToken();
}
}
return Observable.error(throwable);
});
}
Я звоню isUnauthorized()
в операторе retryWhen()
, где я делаю запрос к серверу
class RetrofitHelper {
static ApiService getApiService() {
return initApi();
}
private static OkHttpClient createOkHttpClient() {
final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request originalRequest = chain.request();
AccessToken accessToken= PreferencesHelper.getAccessToken(BaseApplication.getInstance());
String accessTokenStr = accessToken.getAccessToken();
Request.Builder builder =
originalRequest.newBuilder().header("Authorization", "Bearer " + accessTokenStr);
Request newRequest = builder.build();
return chain.proceed(newRequest);
});
return httpClient.build();
}
private static ApiService initApi(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants._api_url)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(createOkHttpClient())
.build();
return retrofit.create(ApiService.class);
}
}
Но мы недавно добавили Basic Auth
, и теперь при первом запросе я получаю 401
и retryWhen()
пытается обновитьТокен, но все равно получает 401
.То есть doOnNext()
не работает, но сразу onError()
работает
private static Observable<AccessToken> refreshAccessToken() {
return RetrofitHelper.getApiService()
.getAccessToken(
Credentials.basic(
Constants._API_USERNAME, Constants._API_PASSWORD
),
Constants._API_BODY_USERNAME,
Constants._API_BODY_PASSWORD,
Constants._API_BODY_GRANT_TYPE
)
.doOnNext((AccessToken refreshedToken) -> {
PreferencesHelper.putObject(BaseApplication.getInstance(), PreferenceKey.ACCESS_TOKEN_KEY, refreshedToken);
}
});
}
// Api Service
public interface ApiService {
// Get Bearer Token
@FormUrlEncoded
@POST("oauth/token")
Observable<AccessToken> getAccessToken(@Header("Authorization") String basicAuth,
@Field("username") String username,
@Field("password") String password,
@Field("grant_type") String grantType);
}
Вот, скажите, почему это ошибка?Почему при первом запросе я получаю 401
, а со второго запроса все работает?