Skip to content

Instantly share code, notes, and snippets.

@gracietti
Created August 16, 2017 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gracietti/4d5fe6a883a1868e9326da1a53e57c83 to your computer and use it in GitHub Desktop.
Save gracietti/4d5fe6a883a1868e9326da1a53e57c83 to your computer and use it in GitHub Desktop.
Changes needed on RetrofitHelper to add logics to refresh Auth0 token automatically
object RetrofitHelper {
(...)
private fun rebuildRetrofit(useAuth: Boolean) {
val client = buildOkHttpClient(useAuth)
retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.API_BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(buildGson()))
.client(client)
.build()
}
private fun buildOkHttpClient(useAuth: Boolean): OkHttpClient {
this.usingAuth = useAuth
var builder = OkHttpClient.Builder()
builder = addLoggingInterceptor(builder)
//This synchronized(builder) will make sure only one call to refresh the Auth0 token will be done at a time
synchronized(builder) { builder = addTokenAuthenticator(builder) }
return builder.build()
}
private fun addTokenAuthenticator(builder: OkHttpClient.Builder): OkHttpClient.Builder {
//AUthenticator is called whenever a response is returned with 401 status code. In this case, you should refresh the token and perform the request again
val auth0Authenticator = object: Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
val accessToken = SessionHelper.instance.accessToken
if (accessToken != null) {
val newAccessToken = SessionHelper.instance.refreshCredentials()
if (usingAuth && newAccessToken != null) {
return response.request().newBuilder().addHeader("Authorization", "Token $newAccessToken").addHeader("X-TOKEN-CLIENT-ID", clientId).build()
} else return null
} else return null
}
}
builder.authenticator(auth0Authenticator)
// This interceptor will add the token to the header on every call, unless Authenticator has already added a new access token
val tokenInterceptor = Interceptor { chain ->
var newRequest = chain.request()
val accessToken = SessionHelper.instance.accessToken
if (usingAuth && !accessToken.isNullOrBlank() && newRequest.header("Authorization").isNullOrBlank()) {
newRequest = newRequest.newBuilder().addHeader("Authorization", "Token $accessToken").addHeader("X-TOKEN-CLIENT-ID", clientId).build()
}
chain.proceed(newRequest)
}
builder.addNetworkInterceptor(tokenInterceptor)
return builder
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment