When using JWTs or OAuth tokens, one challenge is:
βWhat happens when the access token expires?β
Answer: Use a Refresh Token.
π§ Why Refresh Tokens Exist
-
Access tokens should be short-lived (e.g., 15 mins).
-
But logging the user in every 15 mins? π€― No thanks.
-
So we issue a long-lived refresh token to get new access tokens silently.
π How Refresh Tokens Work (Simplified Flow)
-
User logs in
-
Server returns:
-
access_token
(expires soon) -
refresh_token
(expires later or never)
-
-
-
Client uses access_token for API calls.
-
When it expires, client sends:
POST /token/refresh Authorization: Bearer <refresh_token> ```
-
Server verifies it, and returns a new
access_token
.
π‘οΈ Secure Refresh Token Strategy
π Best Practice | Why |
---|---|
Store refresh tokens securely (e.g., EncryptedSharedPreferences on Android) | Prevent token theft |
Rotate refresh tokens on every use | Prevent reuse attacks |
Invalidate old refresh tokens immediately after rotation | Avoid replay |
Bind token to device / IP / fingerprint | Add extra layer of safety |
Donβt send refresh tokens to 3rd-party frontends | Theyβre long-lived and sensitive |
π Token Rotation (Modern Best Practice)
Each time a refresh token is used, issue a new one and invalidate the old.
-
Prevents replay attacks (stealing and reusing a refresh token).
-
Some services (e.g., Auth0, Okta) do this by default.
plaintext
CopyEdit
User β refreshes β gets new access + new refresh Old refresh β marked invalid
π₯ Android-Specific Notes
-
Store access/refresh tokens in:
-
EncryptedSharedPreferences (recommended)
-
Jetpack Security Crypto Library
-
-
NEVER store in plaintext.
-
Always prefer using AppAuth or FirebaseAuth over rolling your own flow.
π§ Gotchas
-
Donβt use the same refresh token forever. Rotate.
-
Handle refresh token expiration (e.g., user logs in again).
-
Monitor refresh usage for abuse detection.