KTokenRefresher

Contract for automatic token refresh on 401 responses.

Kindling provides a default implementation via KDefaultTokenRefresher. Implement this interface directly when your refresh logic requires custom behaviour (different API shape, multi-server setup, custom storage, etc.).

The implementation is passed to KHttpConfig.tokenRefresher and invoked automatically by the internal KTokenRefreshPlugin on every 401 response outside of KHttpConfig.authPaths.

Flow triggered on 401:

shouldRefresh() == true
└─ refresh()
├─ success → applyToken(request) → retry
└─ failure → onRefreshFailed()

Concurrency is handled by Kindling via SingleFlight — if multiple 401s occur simultaneously, only one refresh call is executed and its result is shared across all callers.

Minimal custom implementation:

class CynaTokenRefresher(
private val session: SessionManager,
private val authApi: AuthApi, // your own API, not necessarily Kindling's
) : KTokenRefresher {

override suspend fun shouldRefresh(): Boolean =
session.refreshToken.value != null

override suspend fun refresh(): Boolean = runCatching {
val response = authApi.refresh(session.refreshToken.value!!)
session.saveTokens(response.accessToken, response.refreshToken)
}.isSuccess

override suspend fun applyToken(request: HttpRequestBuilder) {
session.token.value?.let { request.bearerAuth(it) }
}

override suspend fun onRefreshFailed() {
session.clearSession()
}
}

Inheritors

Functions

Link copied to clipboard
abstract suspend fun applyToken(request: HttpRequestBuilder)

Applies the fresh credential to the request that will be retried.

Link copied to clipboard
abstract suspend fun onRefreshFailed()

Called when refresh returned false or threw an exception.

Link copied to clipboard
abstract suspend fun refresh(): Boolean

Performs the token refresh.

Link copied to clipboard
abstract suspend fun shouldRefresh(): Boolean

Called before attempting a refresh.