This is a sample Android application demonstrating token refreshing using Retrofit Authenticator and Kotlin Mutex. It integrates with the DummyJSON API to simulate login and protected requests.
- Kotlin
- Retrofit
- Coroutine Mutex
- Jetpack ViewModel
- MVVM Architecture
- DummyJSON API
- Login with DummyJSON API
- Stores and uses access & refresh tokens
- Automatically refreshes expired tokens using Retrofit Authenticator
- Two authenticator implementations:
TokenAuthenticatorMutex
: Uses KotlinMutex
to safely handle concurrent refresh attemptsTokenAuthenticator
: Basic token refresh without synchronization (for comparison/demo)
This project includes two authenticator classes to demonstrate token refreshing:
TokenAuthenticator
– Basic implementationTokenAuthenticatorMutex
– UsesMutex
to prevent multiple refresh calls
You can switch between them in the NetworkModule inside the di
package:
object NetworkModule {
@Provides
@Singleton
fun provideOkhttpClient(
headerInterceptor: HeaderInterceptor,
tokenAuthenticator: TokenAuthenticatorMutex // ← Change this to TokenAuthenticator to test without Mutex
): OkHttpClient {
return RetrofitHelper.getOkHttpClient()
.addInterceptor(headerInterceptor)
.authenticator(tokenAuthenticator)
.build()
}
}
- Retrofit Interceptor: Adds Authorization header
- Authenticator: Automatically refreshes token on 401 errors
- Mutex: Prevents multiple token refreshes at the same time
- When the app launches, it shows a Login screen.
- Press the Login button to authenticate using default credentials:
username
:emilys
password
:emilyspass
expiresInMins
:1
→ Token expires in 1 minute
- After login, you are redirected to the Profile screen.
- On the Profile screen, press the Load button to trigger 3 parallel API calls.
- If the token is expired, all 3 calls will receive 401, and:
- Using
TokenAuthenticator
: May trigger 3 refresh calls (undesirable). - Using
TokenAuthenticatorMutex
: Only 1 refresh call happens, others wait for it (thread-safe).
- Using