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
Applies the fresh credential to the request that will be retried.
Called when refresh returned false or threw an exception.
Called before attempting a refresh.