Project specific implementations: Setting up the token refresh mechanism - devrath/RunTracer GitHub Wiki

  • We need to configure the Http-client and how to refresh the token when the shot lived token expires.
  • With ktor plugin it is easy since we can use an auth-plugin to achieve this. Here we define how we load & refresh the token and the plugin will do the rest.
class HttpClientFactory (
    private val sessionStorage: SessionStorage
) {

    fun build(): HttpClient {
        // We need to pass a engine to HttpClient, In our case we pass CIO engine
        return HttpClient(CIO) {
            // PLUGIN: Everything related to parsing
            install(ContentNegotiation) {
              // CODE IMPLEMENTATION
            }
            // PLUGIN: Logging Everything related to logging
            install(Logging) {
                // CODE IMPLEMENTATION
            }
            // PLUGIN: We can configure every single request looks like, It is similar to Intercepts in okhttp
            defaultRequest {
                // CODE IMPLEMENTATION
            }
            // PLUGIN: Here we set up the refresh mechanism for the tokens
            install(Auth) {
                // Our mechanism in backend is called bearer mechanism
                bearer {
                    // How the tokens look like: In our case we get from local storage
                    // Ktor attach to every single request
                    loadTokens {
                        // Get token from local storage
                        BearerTokens(
                            accessToken = // Add access token
                            refreshToken = // Add refresh token
                        )
                    }
                    // Refresh token is called when the access token is expired
                    refreshTokens {
                        /**
                         * When the ktor calls the api and returns 401 status code, it will call the refresh token method
                         * and here we can call the refresh token and get the new token
                         */

                        // Call the refresh token API and get the response
                        
                        if(response is Result.Success) {
                            
                            // Now attach the new tokens to the new request
                            BearerTokens(
                                accessToken = // Add from Api
                                refreshToken = // Add from Api
                            )
                        } else {
                            // If response is failure, Then set to a empty one so failure is sent by API
                            BearerTokens(
                                accessToken = "",
                                refreshToken = ""
                            )
                        }
                    }
                }
            }
        }
    }
}