Hello every one. I have a simple problem but don’t...
# ktor
d
Hello every one. I have a simple problem but don’t know how to solve it. When I try accessing an endpoint closed by authorization with an expired token, I need to update it using the refresh token and repeat the request. How to add something like an interceptor to the my httpClient? Example code for request:
Copy code
val httpClient = HttpClient()

GlobalScope.launch(ApplicationDispatcher) {
    try {
        val url = servUrl
        val json = httpClient.get<String>{
            header("Authorization", "Bearer " + Token.getAccessToken())
            url(url)
        }

        success(json)
    } catch (ex: Exception){
        failure(ex)
    }
I would really appreciate any advice. I’m new at ktor and kotlin
c
See https://ktor.io/servers/index.html#features - if u need further help please feel free to ask again - hope this will help you
d
Thanks for answer. I read this article but don`t understand how solve my problem. I think this case is very frequency. Could someone share an example code
c
// cc @e5l
e
Hi @Darmaheev, we have WIP feature here: https://github.com/ktorio/ktor/pull/1310 and it looks like it’s almost what you need
v
Copy code
class TokenManager(private val client: AuthClient) : CoroutineScope {
    val tokenChannel = async { ConflatedBroadcastChannel(newToken()) }
    private val tokenUpdateJob = launch {
        with(tokenChannel.await()) {
            while (true) {
                delay(value.expiresIn)
                send(
                    runCatching { updateToken(value) }.getOrElse { newToken() }
                )
            }
        }
    }
    private suspend fun newToken() = client.clientToken()
    private suspend fun updateToken(token: TokenResponse) = client.updateToken(token.refreshToken)

    suspend fun token() = tokenChannel.await().value
}
If it is possible I would preffer to check if the token is expired before using it. The sample above may not be good for your case, my goal was to persist each updated token in local storage and that's why I am using Channel. Maybe someone could present better way to do it...
d
Thanks