Implementing a Global Authentication Interceptor

Refresh your server access token with an OkHttp interceptor

Siva Ganesh Kantamani
Aug 13 · 3 min read
Image for post
Image for post
Photo by Alexandru Acea on Unsplash

In this article, you’re going to learn how to implement a global authentication interceptor. The job of this interceptor is to refresh the access token when you got an unauthorized response.


Introduction

Updating your server to SSL doesn’t necessarily mean you’re safe out in the wild. Your server needs confirmation that you’re communicating with the user without any hacker interception (mostly stated as the man in the middle attack).

Quick Note: Use a certificate pinning feature to avoid man in the middle attacks in most cases. You can learn what certificate pinning is and how to implement it in Android from this article.

Although we have certificate pinning, it’s better to have some sort of user verification. There are different approaches to verify that you’re communicating with the actual user, one of which is token verification. It might be either standard JWT token or your custom logic.

If we see this token verification at a high-level, it’ll be something like this: First, you’ll perform a regular service call if the response status code is 401, which means unauthorized, it might be a hacker interception, or the actual token is expired. In which case, we have to request a new access token. If the token is generated, then we’ve to reinitialize the original request flow. If not, we should log out the user, assuming the connection is compromised.


Interceptor

Enough with the theoretical part, let's start with what an interceptor is. An interceptor is a powerful mechanism that can monitor, rewrite, and retry service calls. Here's a simple interceptor that logs the outgoing requests and the incoming responses.

Simple logging interceptor using OkHttp3 library

addInterceptor is the function through which we can add an interceptor to the request builder, OkHttp builder. Then we created a new instance of an interceptor in which we obtain the interceptor.chain as input.

From this chain, we can get the request object, which contains in-detailed information about the request body, headers, and more. Once the request completes, we can access the response.

When the proceed function with therequest object invoked on the chain instance, the actual execution will start. The output of the proceed function is the response from the server, including additional information like status code and other stuff.


Authentication Interceptor

Now that we understand how to create an interceptor and how it works, let’s start building the authentication interceptor.

This interceptor’s goal is to invoke a refresh of the access token functionality when the origin request emits unauthorized access. After successfully retrieving the refreshed token, we need to instantiate the request. Have a look:

Authentication interceptor logic

In the first step, we created the original request object to reinitialize it if we get unauthorized access. In the next step, we invoked the proceed function on the chain with the request object.

By this time, the request is started executing. Once the request is completed, we will get the response, and the very first thing we need to do is to verify the request is successful by comparing the status code. If the status code is 200 in the response, then the request is successfully executed.

If the request is a success, then we have to return the response directly. If not, we need to check the error type using the status code. If the status code is 401, then it is unauthorized access; likewise, if you wish to handle other errors, we need to implement it in the else block.

If the origin request response is unauthorized, then we need to create a new request to invoke the getAccessToken service call. Once we obtain the response first, we need to save the latest access token in preference for future use.

After that, we need to update the latest token in the original request object and then re-initiate the request.


Optimization

That’s all. Now, your app has a global authentication interceptor. To make the code a bit more optimized, we can create a new class that extends the interceptor and includes the logic related to authentication here. In this way, we can isolate the interceptor’s functionality, so the code looks more organized. Have a look:

Error handling interceptor by code isolation

To add the interceptor, we need to create an instance of ErrorHandlingInteceptor, as shown below:

val client = OkHttpClient.Builder()
client
.addInterceptor( ErrorHandlingInteceptor())

Better Programming

Advice for programmers.

Thanks to Zack Shapiro

Siva Ganesh Kantamani

Written by

Learn. Code. Write. Repeat. Visit me at https://about.me/sivaganesh_kantamani & Join my email list at https://tinyletter.com/Siva_Ganesh_Kantamani

Better Programming

Advice for programmers.

Siva Ganesh Kantamani

Written by

Learn. Code. Write. Repeat. Visit me at https://about.me/sivaganesh_kantamani & Join my email list at https://tinyletter.com/Siva_Ganesh_Kantamani

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store