Hi team, How `refreshTokens` works while using `Au...
# ktor
p
Hi team, How
refreshTokens
works while using
Auth
plugin with
bearer
provider? In my understanding it should be invoked as soon as server returns 401 in the response. Unfortunately its not working for me. Can anyone please help code for reference
Copy code
fun RemoteDataModule() =
    module {
        single<HttpClient> {
            HttpClient {
                // converts response into dto objects
                install(ContentNegotiation) {
                    json(HttpClientUtil.nonStrictJson)
                }

                // Log HTTP request and response
                install(Logging) {
                    logger = HttpClientLogger // custom logger
                    level = LogLevel.ALL
                }.also { initLogger() } // this will initialise napier for both platform

                //Add authentication header in the request
                install(Auth) {
                    bearer {
                        loadTokens {// add BearerTokens in header
                            val appPreferenceDataSource = get<AppPreferencesDataSource>()
                            val accessToken = appPreferenceDataSource.getAccessToken().first() ?: ""
                            val refreshToken = appPreferenceDataSource.getRefreshToken().first() ?: ""

                            BearerTokens(accessToken, refreshToken)
                        }

                        /**
                         * This block is called when API returns 401, UnAuthorized
                         * In that case it will automatically hit the same API with updated token
                         */
                        refreshTokens {
                            // Refresh tokens and return them as the 'BearerTokens' instance
                            val appPreferenceDataSource = get<AppPreferencesDataSource>()
                            val accessToken = appPreferenceDataSource.getAccessToken().first() ?: ""
                            val refreshToken = appPreferenceDataSource.getRefreshToken().first() ?: ""

                            BearerTokens(accessToken, refreshToken)
                        }
                    }
                }

                defaultRequest {
                    // Set the Content-Type header for each request
                    header(HttpHeaders.ContentType, ContentType.Application.Json.toString())
                    header("Client-id", AppConstants.UNIGO_ORG_ID)
                }
            }
        }

        single<KtorApiService> { KtorApiServiceImp(get<HttpClient>()) }
    }
a
It seems like you don't refresh tokens but just load them the same way from cache twice inside load and refresh blocks. You should call the API endpoint for new tokens and save them to the cache.
p
@Alexander Zhirkevich I am updating the token in cache at success block of token api. I have checked it. The chache is being updated before calling the secured API. Will it not work this way?
a
Can you check that the
WWW-Authenticate
header is present and contains the
Bearer
auth scheme?
p
@Aleksei Tirman [JB] It's not currently present in the header. I'll try once more with the response header as per your suggestion. But is it really needed? According to the official documentation
WWW-Authenticate
is only needed when multiple providers are used, Otherwise just 401 should be enough to call the
refreshToken{}
block. Please correct me if I am wrong here. Attached is the SS of the official document for reference.
a
You're right. Can you please check with the header anyway?
p
Sure, Will try and let you guys know. Meanwhile, Do you think how we create instance of the client matters in this case? I am using
koin
for DI and creating the client as
single
instance. Can it be a problem here?
a
It shouldn't be a problem.