https://kotlinlang.org logo
Title
t

Trey

05/04/2022, 8:31 PM
Is there a way to have the client rebuild a url when establishing a web socket connection? My company requires the token to be in the query param because browsers can't use headers for a web socket. The AuthProvider refreshes the token successfully, but then uses the same url on the retry connection, which causes it to fail with a 401 response again.
a

Aleksei Tirman [JB]

05/07/2022, 11:03 AM
You can send the reference to a request to a channel and then receive it in the
refreshTokens
lambda to modify it before sending retried request. Here is an example:
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.client.plugins.auth.*
import io.ktor.client.plugins.auth.providers.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch

suspend fun main(): Unit = coroutineScope {
    val requestChannel = Channel<HttpRequestBuilder>()

    val client = HttpClient(Apache) {
        install(Auth) {
            bearer {
                loadTokens {
                    BearerTokens("", "")
                }
                refreshTokens {
                    val context = requestChannel.receive()
                    // Here goes a code for getting a new token
                    val newToken = "123"
                    context.parameter("auth", newToken)
                    BearerTokens(newToken, "")
                }
            }
        }
    }

    client.get {
        url {
            host = "127.0.0.1"
            port = 3030
            path("/")
        }

        launch {
            requestChannel.send(this@get)
        }
    }
}
This solution isn’t optimal but should work even for Websockets requests.
👍 1