Introduction
In this article, we will be discussing the process of refreshing JSON Web Tokens (JWTs) in an Android app using Retrofit. JWTs are widely used for authentication in web and mobile applications. They allow for secure transmission of information between parties, but it’s important to refresh them regularly to maintain the security of the application.
In this article, I’ll be showing you how to implement a JWT refresh process in an Android app using Retrofit and OkHttp. Let’s get started.
Checkout the complete hands-on tutorial here
Setting up the Android project
First, we need to set up the Android project by installing the necessary dependencies. These include Retrofit, OkHttp, and a JSON Web Token library. We will also configure the network request in the Android project using Retrofit.
Here’s an example of how to install the Retrofit library in your build.gradle file:
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
And here’s an example of how to configure the Retrofit request:
val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build()
Create an Interceptor to add tokens to API calls
Next, we’ll be creating an OkHttp Interceptor to add token in the headers of our API requests.
class AuthInterceptor: Interceptor { override fun intercept(chain: Chain): Response { val token = getFromStorage() val request = chain.request() if (token.isNullOrEmpty()) { val newRequest = request .newBuilder() .header("Authorization", "Bearer $token") .build() return chain.proceed(newRequest) } return chain.proceed(request) } }
Add interceptor to Retrofit client
Now, we will create a OkHttp client to which we will add this interceptor and then it will be added to our Retrofit builder.
private fun getRetrofit(): Retrofit { val authInterceptor = AuthInterceptor() val okHttpClient = OkHttpClient.Builder() .addInterceptor(authInterceptor) .build() return Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build() }
Modify Interceptor to handle token refresh mechanism
Since we have added tokens to our each requests, there might be the case when token is not present or it is invalid and the request throws error with status code 401. In that case we need to refresh the token, save it to local storage and make the original request again.
class AuthInterceptor: Interceptor { private fun refreshToken():Response { // make an API call to get new token return if (response.isSuccessful) { val token = response.body()?.token saveTokenToLocalStorage(token) val newRequest = request .newBuilder() .header("Authorization", "Bearer $token") .build() chain.proceed(newRequest) } else { chain.proceed(request) } } override fun intercept(chain: Chain): Response { val token = getFromStorage() val request = chain.request() if (token.isNullOrEmpty()) { val newRequest = request .newBuilder() .header("Authorization", "Bearer $token") .build() val response = chain.proceed(newRequest) return if (response.code() == 401) { refreshToken() } else { response } } else { refreshToken() } return chain.proceed(request) } }
refreshToken() function will make a new API call to get a new token from the server and then it will be updated in our local storage following which we can make the original request again with the refreshed token.
Conclusion
Refreshing JWT tokens in Android is crucial for ensuring the security of your API calls. By using OkHttp Interceptor, you can automate the process and make it effortless. I hope this example might help you understand the implementation of JWT token refresh in Android and equipped you with the necessary skills to integrate it in your own projects.
This article was previously posted on proandroiddev.com