Token Management

How the Android SDK manages your user’s tokens

PassageTokenStore

When you create an instance of Passage you also get an instance of PassageTokenStore

Get auth token

You can access the current auth token this way:

val token = passage.tokenStore.authToken

Get refreshed auth token

If you've setup refresh tokens in your app (strongly recommended), the Passage Token Store handles refreshing the auth token for you before it expires. If you have short lived auth tokens, it is highly recommended you use the getValidAuthToken suspend method instead of the above property, so you don't have to worry about using an expired token.

suspend fun exampleGetRequest() {
    val token = passage.tokenStore.getValidAuthToken()
    // Use token
}

How are tokens stored?

Your user's auth token and refresh token are both stored on device using Android's own Encrypted Shared Preferences (opens in a new tab) library. When you sign out your user, the tokens are revoked on the server and removed from the device.

Get tokens from auth methods

Any successful authentication call you make (see Passkey Authentication and Email/SMS Authentication) returns a AuthResult which contains your user's auth token and refresh token.

For example:

suspend fun login() {
    try {
        val authResult = passage.passkey.login()
        val authToken = authResult.authToken // String
        val refreshToken = authResult.refreshToken // String?
        val expiration = authResult.refreshTokenExpiration // Int?
    } catch (e: LoginWithPasskeyException) {
        // ..
    }
}

You can then store and mange them however you choose.

Authenticate PassageUser requests

To make a request on a CurrentUser like passage.currentUser.changeEmail(newEmail) you'll first need to provide that auth token to the Passage class.

passage.currentUser.changeEmail("new@email.com")

Refresh and revoke tokens

You can use the PassageTokenStore methods to refresh or revoke tokens like this:

suspend fun getNewTokens(oldRefreshToken: String) {
    try {
        val authResult = passage.tokenStore.refreshAuthToken(oldRefreshToken)
        val newAuthToken = authResult.authToken
        val newRefreshToken = authResult.refreshToken
        val newExpiration = authResult.refreshTokenExpiration
    } catch(e: PassageTokenException) {
        when (e) {
            is PassageTokenUnauthorizedException -> {
                // Refresh token is no longer valid
            }
        }
    }
}
 
suspend fun clearAndRevokeTokens() {
    try {
        passage.tokenStore.clearAndRevokeTokens()
    } catch (e: PassageTokenException) {
        // ..
    }
}