Я хочу добавить вызов токена обновления в моем методе authenticate HttpAuthenticationInterceptor для управления истечением access_token для unAuthorized ответа 401.
Я добавил синхронный вызов refresh_token в методе authenticate с использованием интерфейса serviceClient (serviceGateway) retrofit 2.но я сталкиваюсь с проблемой циклической зависимости при введении serviceGateway в перехватчик.Нужно ли создавать отдельный интерфейс ServiceClient для этого вызова токена обновления?
Вот мои классы AuthenticationInterceptor и NetworkModule
class AuthenticationInterceptor @Inject constructor(private val preferences: SharedPreferencesKeyValueDataSource, private val serviceGateway: ServiceGateway) : Interceptor, Authenticator{
@Throws(IOException::class)
override fun authenticate(route: Route?, response: Response): Request?{
if (response.code() == 401) {
val credentials = Credentials.basic("dummy", "dummy")
val refreshCall = serviceGateway.refreshToken(credentials, preferences.getValue(Constants.REFRESH_TOKEN, ""))
//make it as retrofit synchronous call
val refreshResponse = refreshCall.execute()
return if (refreshResponse.code() == 200) {
//Save the access token and refresh token in preferences
refreshResponse.body()?.let{
preferences.setValue(Constants.ACCESS_TOKEN, it.access_token)
preferences.setValue(Constants.REFRESH_TOKEN, it.refresh_token)
}
val newAccessToken = refreshResponse.body()?.access_token
response.request().newBuilder()
.header(AuthenticationInterceptor.AUTHORIZATION, "Bearer $newAccessToken")
.build()
} else {
null
}
}
return null
}
}
// А код из NetworkModule приведен ниже,
@Provides
@Singleton
fun provideAuthenticationInterceptor(preferences: SharedPreferencesKeyValueDataSource, serviceGateway: ServiceGateway) = AuthenticationInterceptor(preferences, serviceGateway)
@Provides
@Singleton
fun provideOkhttpClient(loggingInterceptor: HttpLoggingInterceptor,
authenticationInterceptor: AuthenticationInterceptor): OkHttpClient {
val client = OkHttpClient.Builder()
client.addInterceptor(loggingInterceptor)
client.addInterceptor(authenticationInterceptor)
client.authenticator(authenticationInterceptor)
client.connectTimeout(15, TimeUnit.SECONDS)
client.readTimeout(20, TimeUnit.SECONDS)
return client.build()
}
@Provides
@Singleton
fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient,
@Named("BASE_URL_CORE") baseUrl: String)
: Retrofit {
return Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
}
@Provides
@Singleton
fun provideGateway(retrofit: Retrofit): ServiceGateway {
return retrofit.create(ServiceGateway::class.java)
}
Ошибка компилятора ...
- ServiceGateway вводится в ... NetworkModule.provideAuthenticationInterceptor (…, serviceGateway)
- AuthenticationInterceptor вводится в
...NetworkModule.provideOkhttpClient (…, authenticationInterceptor) - okhttp3.OkHttpClient внедряется в ... NetworkModule.provideRetrofit (…, okHttpClient,…)
- retrofit2.Retrofogger at injected.provideGateway (дооснащение)