dev.farmer
dev.farmer

Reputation: 2779

How to refresh the JWT token before calling the REST API in android? (Retrofit, Rx)

I am developing an android app using Kotlin, RxJava(RxKotlin), Retrofit.

Our service uses the JWT token.

It is not difficult to refresh the expired token, before sending a REST API.

But my problem is that...

Some UI calls multiple REST API in concurrently.

For example, 5 API Requests are sent to the server in MainActivity concurrently.

If the token was already expired, I will receive 5 errors with 401 http error code (token expired).

But in my case, I check whether the token is expired or not.

If the token is expired, I try to refresh the token.

So in this example, I send 5 requests for refreshing the token.

Then... I will get the 5 new JWT tokens...

My better idea is that...

Before I send the 5 REST requests, I can check whether the token is expired or not.

But the problem is... I have a lot of this kind of UIs.

So I need a more beautiful way.

I think this kind of code (checking the token before send requests in UI) can solve my problem.

But this code is redundant, boilerplate code...

I want to solve this problem with just one entrance.

I'm really sorry about my stupid English skill.

Upvotes: 1

Views: 2728

Answers (1)

shafayat hossain
shafayat hossain

Reputation: 1129

You can handle this situation centrally. OkHttpClient has a method, called authenticator(). When any response get unauthorized exception, it is called. An example is as following (I'm using kotlin here):

OkHttpClient.Builder()
    .authenticator(object: Authenticator {
        override fun authenticate(route: Route?, response: Response): Request? {
            if(response.code == 401) {
                // build retrofit client manually and call refresh token api
                val refreshTokenService = retrofitClient.create(RefreshTokenService::class.java)
                val refreshTokenResponse = refreshTokenService.refreshToken().execute()
                val token = refreshTokenResponse.body().token
                return response.request.newBuilder().header("Authorization", token).build()
            } else {
                return response.request
            }                
        }
    })

Add this client to retrofit. You have to change refresh token login inside this authenticator.

Upvotes: 5

Related Questions