Auth Tokens & Idempotency Flashcards

DATA › Networking

Walk the full lifecycle of an access token in a mobile app.
Authenticate (credentials/OAuth) to receive an access token (short-lived) and refresh token (long-lived). Cache securely, attach the access token to each request, detect expiry (clock or 401), exchange the refresh token for a new pair, handle rotation/revocation, and wipe everything on logout.
Define idempotency and explain why retries need it.
An operation is idempotent when performing it N times has the same effect as once. After a timeout the client doesn't know whether the server executed the call, so it can only retry safely if the retry cannot double the effect (e.g. double-charge a card).
What is an idempotency key and how does the server use it?
A unique client-generated id (e.g. a UUID per logical operation) sent with the request. The server stores the result keyed by it; a retry with the same key returns the stored result instead of re-executing. Same key + same result = safe retries for non-idempotent verbs like POST.
Twenty coroutines hit getToken() while the token is expired. What must happen, and what are the two standard shapes?
Exactly one refresh runs and all callers receive its result (single-flight). Either a Mutex: withLock { re-check expiry; refresh if still needed }, or cache a shared Deferred/flow of the in-flight refresh that everyone awaits.
Why must you re-check token expiry AFTER acquiring the refresh lock?
While you waited for the lock, the previous holder probably completed the refresh. Without the re-check every queued caller performs its own refresh in turn: serialized, but still N refreshes. Check-then-act must happen inside the critical section.
What goes wrong when refresh is NOT single-flight?
A thundering herd of refresh calls; with refresh-token rotation the first response invalidates the others' tokens (some callers store a dead token); rate limits and server load spike; and the cached state can interleave into an inconsistent pair.
A caller awaiting the shared refresh is cancelled. What should and shouldn't happen?
That caller stops waiting, but the refresh itself should continue for the other awaiters, so run it in an owned scope (or protect the critical write with NonCancellable) rather than in the first caller's job. A Mutex must be released on the way out (withLock does this in finally).
How do refresh-token rotation and reuse detection improve security?
Each refresh returns a NEW refresh token and invalidates the old one. If a stolen (old) refresh token is later replayed, the server sees reuse of an invalidated token, treats the whole token family as compromised, and revokes it, limiting how long a leaked token is useful.
Where should tokens be stored on Android, and where must they never appear?
In Keystore-backed encrypted storage (e.g. encrypted DataStore/prefs); memory for the hot copy. Never: plaintext SharedPreferences, files, logs or crash reports, URLs/query params, or hardcoded in the APK. Mask auth headers in any logging interceptor.

Back to Auth Tokens & Idempotency