With the new bearer token client auth feature, our...
# ktor
c
With the new bearer token client auth feature, our app has two kinds of oauth tokens: authenticated and unauthenticated. Each has a separate token and refresh token. The unauthenticated tokens are used for guest users. I'd like to figure out a way to replace the guest tokens after the user has authenticated with either user/pw or social token, but the current feature seems pretty limited. Does anyone know how I might accomplish this? Should I create a new client?
a
I would recommend implementing your own way of storing tokens instead of relying on Ktor's storage and its associated logic. Could you please share a little code sample to better understand your problem?
c
I don't have much code yet. It's a greenfield project using an old API. Currently, I have this:
Copy code
install(Auth) {
                bearer {
                    loadTokens {
                        withContext(backgroundDispatcher) {
                            val code = client.get(URL_REQUEST_GRANT)
                            val r = <http://client.post|client.post>(urlRequestAccessToken(code.code))
                            BearerTokens(accessToken = r.accessToken, refreshToken = r.refreshToken)
                        }
                    }
//...
However, that only provides an unauthenticated guest token. I then need UI in the app to accept either an email/pw or social token in order to login and generate an authenticated token. I could potentially generate a new
HttpClient
for authenticated requests, but there's probably a better way. Ultimately, I'd see if I have an authenticated token in storage before deciding if I should make an authenticated request or if I should say, return to the login screen.
a
So do you have a server in place to get an authenticated token? I see a problem that an HTTP client stores just one pair of access/refresh tokens but you would have multiple clients with a server. If you always have a single guest token then you could save an authenticated token in the user's session or in any other kind of storage. In this case, authenticated tokens will be stored separately and it would be easy to check for their existence. Please correct me if misunderstood something.
c
I think it's like this... We need the guest/unauthenticated token and refresh token in order to login and to perform REST requests as a guest. After we're logged in, we need to switch out the tokens so the server knows who's making the requests, even for calls which a guest is allowed to make. After logout, we want to either use the old guest tokens or generate new ones, but probably the latter.
As for storage of the authenticated tokens, we're using Touchlab's multiplatform-settings library with encryption through either encrypted SharedPreferences (Tink/Jetpack Security) or Apple's keystore. I guess I need some way to override the guest tokens if authenticated tokens are stored.
a
Unfortunately, you don't have direct access to
tokensHolder
property since it's private.
IMHO in your case, I would go without Ktor's bearer auth provider functionality and implement guest tokens storage and loading/refreshing of tokens by myself. Just to not complicate things.
c
I understand. Thanks for the help. I think I saw some Ktor client examples earlier of implementing token refresh on 401 errors. I'll go look.