title: How to refresh token using okhttp authenticator with multiple request at a time
body: <p>I am using retrofit for networking in my project. The problem is I have to call 2 requests from my first activity. It works fine but when the access token expires it has to refresh token. I have implemented a call using okhttp Authenticator. But it is calling multiple times and this error is showing too <code>too many followup request 21</code></p>
  
  <p><strong><em>EDIT</em></strong>
  I updated TokenAuthenticator class and added synchronized(). but it is returning from <code>if (originalRequest.header("Authorization") != null) return null</code> . I am following this answer <a href="https://stackoverflow.com/a/52513122/10243953">https://stackoverflow.com/a/52513122/10243953</a></p>
  
  <p>If i am removing <code>if (originalRequest.header("Authorization") != null) return null</code> this line then its working but in log report i see its calling for refresh token multiple times. How can i avoid this multiple time calls?</p>
  
  <p><strong>This is my Authenticator class</strong></p>
  
  <pre><code>class TokenAuthenticator : Authenticator {
  
  private val refreshTokenGrandType = "refresh_token"
  private var oldToken: String? = null
  private var newToken: String? = null
  
  override fun authenticate(route: Route?, response: Response?): Request? {
      oldToken = SharedPreferenceManager(MainApplication.applicationContext()).getToken()
      if (response == null) return null
      val originalRequest = response.request()
      if (originalRequest.header("Authorization") != null) return null
      if(!isTokenSaved()){
          synchronized(this) {
              RetrofitClient.client.create(Auth::class.java).refresh_token(
                  SharedPreferenceManager(MainApplication.applicationContext()).getRefreshToken()!!,
                  refreshTokenGrandType
              ).enqueue(object : Callback&lt;Token&gt; {
                  override fun onFailure(call: Call&lt;Token&gt;, t: Throwable) {
                      Toast.makeText(
                          MainApplication.applicationContext(),
                          t.message,
                          Toast.LENGTH_SHORT
                      ).show()
                      Log.d("TokenAuth", t.message!!)
                  }
  
                  override fun onResponse(
                      call: Call&lt;Token&gt;,
                      response: retrofit2.Response&lt;Token&gt;
                  ) {
                      if (response.isSuccessful) {
                          val body = response.body()
                          newToken = body!!.access_token
                          val refresh_token = body.refresh_token
  
                          SharedPreferenceManager(MainApplication.applicationContext()).accessToken(
                              newToken!!,
                              refresh_token
                          )
  
                      } else {
                          val error = response.errorBody()
                          Log.d("TokenAuthRes", error!!.string())
                      }
                  }
              })
          }
      }
      return originalRequest
          .newBuilder()
          .header(
              "Authorization",
              "Bearer ${SharedPreferenceManager(MainApplication.applicationContext()).getToken()}"
          )
          .build()
  
  }
  
  fun isTokenSaved() : Boolean{
      if (newToken == null) return false
      if (oldToken.equals(newToken)) return false
      else return true
  }
  }
  </code></pre>
  
  <p><strong>Retrofit client</strong></p>
  
  <pre><code>object RetrofitClient {
  private lateinit var interceptor : Interceptor
  private lateinit var okHttpClient: OkHttpClient
  private var retrofit : Retrofit? = null
  
  val client : Retrofit
      get(){
          val context : Context = MainApplication.applicationContext()
          interceptor = Interceptor { chain -&gt;
              val url = chain.request()
                  .url()
                  .newBuilder()
                  .build()
  
              val request = chain.request()
                  .newBuilder()
                  .addHeader("Authorization","Bearer ${SharedPreferenceManager(context).getToken()}")
                  .url(url)
                  .build()
  
              return@Interceptor chain.proceed(request)
          }
  
          okHttpClient = OkHttpClient.Builder()
              .addInterceptor(interceptor)
              .addInterceptor(NoInternetInterception(context))
              .authenticator(TokenAuthenticator())
              .connectTimeout(1, TimeUnit.MINUTES)
              .build()
  
          if (retrofit == null){
              retrofit = Retrofit.Builder()
                  .client(okHttpClient)
                  .baseUrl(const.URL)
                  .addConverterFactory(GsonConverterFactory.create())
                  .build()
          }
          return retrofit!!
      }
   }
  </code></pre>