Reputation: 91
i wanna add a token to request headers in Interceptor . but now i dont now what should i do.
here is my datastore
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class SettingsManager(context: Context) {
private val dataStore = context.dataStore
val getToken = dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preference ->
preference[token] ?: ""
}
suspend fun setToken(tokenStr: String) {
dataStore.edit { preferences ->
preferences[token] = tokenStr
}
}
companion object {
val token = stringPreferencesKey("token")
}
}
i can not get the context object in Interceptor 。
so i try to use hilt to fix it
class RequestInterceptor(private val settingsManager: SettingsManager) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
runBlocking {
val first = settingsManager.getToken.first()
LogUtil.i("token " + first)
request.newBuilder().addHeader("token", first).build();
}
return chain.proceed(request)
}
}
i dont know the next step @AndroidEntryPoint
cant use on Interceptor class .
plz guys , give me some solutions
Upvotes: 9
Views: 1635
Reputation: 145
This works for me
override fun intercept(chain: Interceptor.Chain): Response {
return runBlocking {
val token = dataStorePreferences.getAuthToken().first()
val request = chain.request().newBuilder().addHeader(AUTHORIZATION_HEADER, "$BEARER $token").build()
val response = chain.proceed(request)
if (response.code == UNAUTHORIZED_CODE) {
try {
dataStorePreferences.setAuthToken(token)
chain.proceed(request.newBuilder().addHeader(AUTHORIZATION_HEADER, "$BEARER $token").build())
} catch (exeption: Exception) {
dataStorePreferences.setAuthToken("")
response
}
} else {
response
}
}
}
Upvotes: 1
Reputation: 509
I just used this way.
suspend fun getToken() : String? {
val preference = dataStore.data.first()
return preference[PREF_JWT_TOKEN]
} // this is inside the datastore local repository.
and inside the intercepter you can get runBlocking UI as this.
val builder = Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
var token: String? = null
runBlocking {
token = dataStorePreferenceRepository.getToken()
if (!token.isNullOrEmpty()) {
val authorized = original.newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
chain.proceed(authorized)
} else {
chain.proceed(original)
}
}
}.addNetworkInterceptor(StethoInterceptor()).build()
return builder.client(client).build().create(ApiInterface::class.java)
and inside the Module class use like this.
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun getDataStorePreferenceRepository(@ApplicationContext appContext: Context): DataStorePreferenceRepository {
return DataStorePreferenceRepository(context = appContext)
}
}
Upvotes: 4
Reputation: 13887
You should be able to see it in Hilt if you just add the @Inject constructor
to your RequestInterceptor.
E.g.
class RequestInterceptor @Inject constructor(private val settingsManager: SettingsManager) : Interceptor {...
And I'm not sure if you can do your SettingsManager like that but you can try class SettingsManager @Inject constructor(@ApplicationContext context: Context) {
Upvotes: 1