Home > OS >  Ktor - Only apply bearer tokens for certain urls
Ktor - Only apply bearer tokens for certain urls

Time:03-03

In my project, there are network requests that require authentication via bearer tokens and some requests that don't. Is there a way to specify the urls that do not need bearer tokens? If I just add the Auth plugin, then I always get a 401 response for the network calls that don't require bearer tokens.

This is my implementation right now:

interface MyService {

    ...

    companion object Factory {
        fun build(getToken: GetToken, login: Login, saveToken: SaveToken): MyService {
            return MyServiceImpl(httpClient = HttpClient(CIO) {
                install(JsonFeature) {
                    serializer = KotlinxSerializer(
                        kotlinx.serialization.json.Json {
                            ignoreUnknownKeys = true
                        }
                    )
                }
                install(Logging) {
                    logger = Logger.DEFAULT
                    level = LogLevel.HEADERS
                }
                install(Auth) {
                    lateinit var tokenInfo: TokenInfo

                    bearer {
                        refreshTokens {
                            getRefreshedTokens(
                                tokenInfo = tokenInfo,
                                login = login,
                                saveToken = saveToken
                            )
                        }
                        loadTokens {
                            tokenInfo = getToken.execute().firstOrNull() ?: TokenInfo(
                                Constants.EMPTY_STRING, Constants.EMPTY_STRING
                            )
                            BearerTokens(
                                accessToken = tokenInfo.accessToken,
                                refreshToken = tokenInfo.refreshToken
                            )
                        }
                    }
                }
            })
        }

        ...
    }
}

CodePudding user response:

You can filter requests by some condition that should include the Authorization header initially. For each other request, the second request with the Authorization header will be made if a server replied with 401 Unauthorized status. Here is an example configuration:

val client = HttpClient {
    install(Auth) {
        bearer {
            sendWithoutRequest { request -> request.url.encodedPath.startsWith("/restricted") }
            // ...
        }
    }
}

CodePudding user response:

A bearer token is nothing but a header Authorization: Bearer XXX - If you're looking for a tech specific way to handle this (drop in some module, etc) then you may be out-of-luck

However, this problem occurs frequently enough in my life - the solution is to actually dynamically manipulate the headers - Basically, use the strategy pattern. If you can create instances of your client, then each instance would get its own strategy. If you can't, then install a function that gets called with every request to determine the header based on whatever logic you need.

In your case, a custom:

  install(Auth) {
    // your code here
  }
  • Related