【问题标题】:JWT Token Wont Update when using dagger 2?使用匕首 2 时 JWT 令牌不会更新?
【发布时间】:2020-08-30 14:40:15
【问题描述】:

我在运行时使用 dagger 2 更新令牌时遇到问题。

所以这里是场景:

我有一个更改密码的屏幕。当我成功更新密码时,当前的 jwt 令牌将无效,我需要从更新令牌响应中存储新令牌,我将该令牌存储在 SharedPreferences 中。但问题是当我存储令牌时。它在 sharedprefernces 中更新,但不会在我构建 Retrofit 实例(授权标头)的 DaggerGraph 中更新值。

下面是我的代码:

AppComponent.kt

@Singleton
@Component(
    modules = [StorageModule::class, AppModule::class, ViewModelModule::class]
)
interface AppComponent {

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance context: Context): AppComponent
    }

    fun inject(activity: SplashActivity)

    fun inject(activity: LoginActivity)

    fun inject(activity: MainActivity)

    fun inject(activity: ChangePasswordActivity)
}

AppModule.kt

@Module
class AppModule {

    @Singleton
    @Provides
    fun provideAuthInterceptor(sharedPreferencesSources: SharedPreferencesSources): Interceptor {
        return AuthInterceptor(sharedPreferencesSources.tokenApi())
    }

    @Singleton
    @Provides
    fun provideApiService(
        authInterceptor: Interceptor
    ): SharedProductClient {
        return Network.retrofitClient(authInterceptor = authInterceptor)
            .create(SharedProductClient::class.java)
    }

    @Singleton
    @Provides
    fun provideAppRepository(apiService: SharedProductClient): AppRepository {
        return AppRepositoryImpl(apiService)
    }

    @Singleton
    @Provides
    fun provideAppUseCase(appRepository: AppRepository): AppUseCase {
        return AppUseCase(appRepository)
    }
   
    @Singleton
    @Provides
    fun provideAppScheduler(): SchedulerProvider = AppSchedulerProvider()
}

StorageModule.kt

@Module
class StorageModule {

    @Singleton
    @Provides
    fun provideSharedPreferences(context: Context): SharedPreferences {
        return context.getSharedPreferences(SharedPrefName, Context.MODE_PRIVATE)
    }

    @Singleton
    @Provides
    fun provideSharedPreferencesSource(sharedPrefInstance: SharedPreferences): SharedPreferencesSources {
        return SharedPreferencesSourcesImpl(sharedPrefInstance)
    }

    companion object {
        const val SharedPrefName = "share_product_prefs"
    }
}

AuthInterceptor.kt

class AuthInterceptor constructor(
    private val token: String
) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response = chain.run {
        proceed(
            request()
                .newBuilder()
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", "Bearer $token")
                .build()
        )
    }
}

任何建议都会对我有帮助。谢谢!

【问题讨论】:

  • 你能把你试图覆盖令牌的地方放在分片偏好中吗?
  • hai,我把 sharedpreferences 放在一个接口中,它的实现。并在 StorageModule.kt 中提供其接口

标签: android kotlin dependency-injection dagger-2 dagger


【解决方案1】:

这是因为您在创建AuthInterceptor 时只传递了令牌的String 实例。

您应该提供一种在需要时从SharedPreferences 动态获取令牌的方法(例如接口)。


这是这样做的一种方法:

  1. token:String 更改为AuthInterceptor 构造函数中的函数类型(并在需要时使用它):
class AuthInterceptor constructor(
    private val tokenProvider: () -> String
) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response = chain.run {
        proceed(
            request()
                .newBuilder()
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", "Bearer ${tokenProvider.invoke()}")
                .build()
        )
    }
}
  1. 在创建 AuthInteceptor 时,构建 lambda 以动态引用 SharedPreferences
@Module
class AppModule {

    @Singleton
    @Provides
    fun provideAuthInterceptor(sharedPreferencesSources: SharedPreferencesSources): Interceptor {
        return AuthInterceptor(){ sharedPreferencesSources.tokenApi() }
    }

    //...
}

这样tokenProvider 将是invokedSharedPreferences 将被访问)每次您进行 api 调用,而不是创建 AuthInterceptor 时只有一次。

【讨论】:

    猜你喜欢
    • 2022-12-23
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多