我想编写身份验证拦截器,它是从本地db的加载访问令牌,并添加到Android Architection Components样机板项目中的请求标题。
Authentication Interceptor类:
class AuthenticationInterceptor: Interceptor, Authenticator {
/*...*/
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
if (!request.url().encodedPath().equals("/login", ignoreCase = true)) {
tokenRepository.getAccessToken().let {
request = request?.newBuilder()
?.addHeader("Authentication", "Bearer " + it)
?.build()
}
}
return chain.proceed(request)
}
override fun authenticate(route: Route, response: Response): Request? {
/*...*/
}
}
appModule类其中,其中将拦截器添加到okhttpclient:
@Module(includes = [ViewModelModule::class])
class AppModule {
/*...*/
@Singleton
@Provides
fun provideTokenService(): TokenService {
return Retrofit.Builder()
.client(
OkHttpClient.Builder()
.addNetworkInterceptor(AuthenticationInterceptor()).build()
)
.baseUrl("http://localhost:8080")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.build()
.create(TokenService::class.java)
}
/*...*/
}
我尝试将存储库添加到构造函数,但必须将存储库注入AppModule,这会导致构建错误
class AuthenticationInterceptor @Inject constructor(val tokenRepository: TokenRepository): Interceptor, Authenticator {
如果我将存储库注入类字段,则存储库将为null
@Inject lateinit var tokenRepository: TokenRepository
所以我的问题如何将存储库注入拦截器?
好吧,我解决了我的问题:
- 首先:我在拦截器上使用构造函数注入
-
第二:我不创建手动新实例,而是将拦截器添加到提供商参数:
fun providetokenservice(authinterceptor:authenticationinterceptor):tokenservice {
-
第三:第二点引起了圆依赖关系,因为存储库使用了服务,因此我不使用interceptor中的存储库而不是使用dao(或创建另一个不使用服务的存储库)