Access token expiration. Refresh Token. Retrofit Interceptor, Coroutines

Manuchekhr Tursunov
3 min readMay 25


I will bring an example of implementation in Kotlin for handling token expiration and refreshing the access token using Retrofit and Coroutines:

First, create an API interface for the token refresh request:

interface ApiService {
suspend fun refreshAccessToken(): TokenResponse

Create a TokenResponse data class to represent the response from the token refresh endpoint:

data class TokenResponse(
@SerializedName("access_token") val accessToken: String,
@SerializedName("expires_in") val expiresIn: Long

Next, you can implement the token refresh logic in your network interceptor or authentication manager class:

class AuthInterceptor(private val apiService: ApiService) : Interceptor {
// Other interceptor configuration and properties

private val sessionManager = SessionManager() // Replace with your session management class

override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val accessToken = sessionManager.getAccessToken()

if (accessToken != null && sessionManager.isAccessTokenExpired()) {
val refreshToken = sessionManager.getRefreshToken()

// Make the token refresh request
val refreshedToken = runBlocking {
val response = apiService.refreshAccessToken()
// Update the refreshed access token and its expiration time in the session
sessionManager.updateAccessToken(response.accessToken, response.expiresIn)

if (refreshedToken != null) {
// Create a new request with the refreshed access token
val newRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer $refreshedToken")

// Retry the request with the new access token
return chain.proceed(newRequest)

// Add the access token to the request header
val authorizedRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer $accessToken")

return chain.proceed(authorizedRequest)

n this example, SessionManager is a class that manages the access token and its expiration time. The isAccessTokenExpired() method checks if the access token has expired based on the current time and the token's expiration time stored in the session. The getAccessToken() and getRefreshToken() methods retrieve the access token and refresh token from the session, respectively. The updateAccessToken() method updates the access token and its expiration time in the session after a successful token refresh.

Make sure to configure Retrofit with the AuthInterceptor when building the OkHttpClient:

val okHttpClient = OkHttpClient.Builder()
// Other OkHttpClient configuration

val retrofit = Retrofit.Builder()
// Other Retrofit configuration

With this implementation, whenever an API request receives a 401 unauthorized response due to an expired access token, the interceptor will automatically trigger the token refresh request, update the access token in the session, and retry the original request with the refreshed access token.

Here’s an example implementation of the isAccessTokenExpired() method in SessionManager class:

class SessionManager {
// Other session management properties and methods

private var accessToken: String? = null
private var accessTokenExpirationTime: Long? = null

// Method to check if the access token has expired
fun isAccessTokenExpired(): Boolean {
val currentTimeMillis = System.currentTimeMillis()
return accessTokenExpirationTime != null && currentTimeMillis >= accessTokenExpirationTime!!

// Method to update the access token and its expiration time in the session
fun updateAccessToken(token: String, expiresIn: Long) {
accessToken = token
accessTokenExpirationTime = System.currentTimeMillis() + expiresIn * 1000 // Convert expiresIn to milliseconds

// Other session management methods

In this example, accessToken is the stored access token, and accessTokenExpirationTime represents the expiration time of the access token. The isAccessTokenExpired() method compares the current time (currentTimeMillis) with the expiration time to determine if the access token has expired. If accessTokenExpirationTime is not null and the current time is greater than or equal to the expiration time, it indicates that the access token has expired.

The updateAccessToken() method is responsible for updating the access token and its expiration time in the session after a successful token refresh or initial login. It takes the new access token (token) and the expiration time in seconds (expiresIn), converts the expiration time to milliseconds, and stores the updated values in the accessToken and accessTokenExpirationTime properties.