I would like to conditionally add authorization (b...
# ktor
j
I would like to conditionally add authorization (bearer token) to a request if a user is authenticated, otherwise send the request as-is. Does Ktor support conditional headers via a plugin?
d
I’m pretty sure you can do this with the Auth plugin already. You might need to create a custom Auth Provider, but it would still be possible.
j
Do you have any links to documentation regarding creating a custom Auth Provider?
s
Depending on your use case, you may be able to use two HttpClient's instead of one. For example, a
AuthenticatedHttpClient
and a
UnauthenticatedHttpClient
j
I didn’t know it was recommended to have multiple HttpClient objects.
d
I often have many. Each configured precisely for the service I’m calling. This is server side though, from the app I’d probably only have one.
s
I don't know this is intended to be done, but I typically make lots of HttpClients that share the same HttpClientEngine. That way all the underlying client resources can be shared, but different parts of the app can have their own config for serde, auth, etc.
plus1 3
m
You can also do something like
Copy code
open val client = httpClient.config {
        defaultRequest {
            if (auth != null) {
                headers[HttpHeaders.Authorization] = "Bearer $auth"
            }
        }
    }
a
Does Ktor support conditional headers via a plugin?
Yes, Ktor supports sending headers conditionally within a plugin. You can find examples in the documentation.
j
@Aleksei Tirman [JB] How does Ktor resolve multiple plugins that each declare a
on(Send) { req ->  ...}
? Is this an invalid use case? I would like to use the existing Auth plugin but I’d also like to add an additional plugin that will conditional add a bearer token based on a certain condition. Looking at the source code it’s not clear if declaring
on(Send)
will work.
a
Ktor executes the interceptors of
on(Send)
in the order they were registered. It's a valid use case. Can you describe the problem in more detail?
d
It seems like you’d be better off creating your own Auth provider, which you can use to add behavior to the Auth plugin. I don’t remember the exact process, as I’m away from my computer. I just remember looking at how the
basic
config block worked, and it was pretty easy to create a custom one.
j
I wanted a way to conditionally add a bearer token to a request if one was available. Turns out I can use the default Auth plugin to achieve this, I just need to make sure the plugin doesn’t wait for a 401 response first, which it was previously.
d
I think there is a flag you can set to do that.
Copy code
sendWithoutRequest { myBearerTokenIsAvailable(it) } // 'it' is a HttpRequestBuilder if you need anything from it.
a
You can find more about the sendWithoutRequest method in the documentation.