Skip to content

Instantly share code, notes, and snippets.

@justasm
Created February 12, 2021 12:57
Show Gist options
  • Save justasm/fcb74cfc0220a39396d9ab660dd4f572 to your computer and use it in GitHub Desktop.
Save justasm/fcb74cfc0220a39396d9ab660dd4f572 to your computer and use it in GitHub Desktop.
OkHttp Interceptor to retry 401 requests after a token refresh
import java.io.IOException
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
class AuthorizationInterceptor(private val delegate: TokenDelegate) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val originalToken = delegate.currentToken
val request = originalToken?.let { token ->
originalRequest.newBuilder().authorize(token).build()
} ?: originalRequest
val response = chain.proceed(request)
if (originalToken == null || response.code != HTTP_UNAUTHORIZED) return response
val latestToken = synchronized(this) {
val latestToken = delegate.currentToken
if (originalToken == latestToken) {
// This is the first synchronization call, update the token
delegate.getNewToken()
} else {
// Token has changed, use the new token
latestToken
}
}
return latestToken?.let { token ->
response.body?.close()
chain.proceed(originalRequest.newBuilder().authorize(token).build())
} ?: response
}
}
interface TokenDelegate {
val currentToken: String?
fun getNewToken(): String?
}
private fun Request.Builder.authorize(token: String): Request.Builder =
header("Authorization", "Bearer $token")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment