while login app i could get TOKEN, refresh token, and save it but i have no idea about when session end for token how to renew. how to add intercepter in it to renew token or some other method could be use ? here is my code
1- Api end point
@POST("identity/Identity/GetRefreshToken")
suspend fun refreshToken(): AuthTokenEntityDT0
2- AuthTokenEntityDT0 response
data class AuthTokenEntityDT0(
@SerializedName("accessToken") val accessToken: String,
@SerializedName("refreshToken") val refreshToken: String,
@SerializedName("statusCode") val statusCode: Int,
@SerializedName("statusMessage") val statusMessage: String,
)
3 - make request here
@Provides
@Singleton
fun provideAPIService(): ApiService {
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.addHeader("Content-Type", "application/json; charset=UTF-8")
.addHeader("user-agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
.addHeader("Authorization", "Bearer $access_token")
val request = requestBuilder.build()
chain.proceed(request)
}
.build()
val retrofit = Retrofit.Builder()
.baseUrl(NativeBaseUrl.getBaseUrl())
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit.create(ApiService::
class.java)
}
@Provides
fun provideApiRepository(apiService: ApiService): ApiRepository {
return ApiRepositoryImpl(apiService)
}
4 -
issue: refreshToken Api Calling repeatedly how i can stop it and moved forward although i have put Dispatcher for one request to move forward like this
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
val dispatcher = Dispatcher()
dispatcher.maxRequests = 1
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(ForbiddenInterceptor(this))
.dispatcher(dispatcher)
.addInterceptor(interceptor)
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.addHeader("Content-Type", "application/json;
charset=UTF-8")
.addHeader("user-agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X
10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
.addHeader("Authorization", "Bearer $access_token")
val request = requestBuilder.build()
chain.proceed(request)
}
.build()
5- here is my intercepter
class ForbiddenInterceptor(var hIltModules: HIltModules) :
Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val original = chain.request()
val response = chain.proceed(original)
if (response.code == 401) {
val responseRefreshTokens= runBlocking {
val originalRequests = chain.request()
val authenticationRequest = originalRequests.newBuilder()
.addHeader("refreshtoken", "${Constants.refreshToken}").build()
chain.proceed(authenticationRequest)
hIltModules.provideAPIService().refreshToken()
}
if (responseRefreshTokens.statusCode == 200) {
val originalRequests = chain.request()
val newAuthenticationRequest = originalRequests.newBuilder()
.removeHeader("refreshtoken")
.build()
access_token = responseRefreshTokens.accessToken
refreshToken = responseRefreshTokens.refreshToken
return chain.proceed(newAuthenticationRequest)
}
}
return chain.proceed(original)
}
}
I suggest you put your custom interceptor in its own class, like this:
class ForbiddenInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
val response: Response = chain.proceed(request)
if (response.code == 401) {
// this code section will run for every HTTP 401 response
}
return response
}
}
Then use this interceptor:
val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(ForbiddenInterceptor())
.build()
Adding the interceptor to the OkHttpClient makes sure you'll intercept the calls and you can run your custom code, check if it's been rejected by the server.
As for renewing your token. You'll probably need to implement another service of the backend. I can only assume, but you'll have to use your accesToken
feed it into an endpoint, the server will return a fresh refreshToken
.