Does Android AccountManager automatically refresh expired scoped auth tokens?
0 reputation · 01 Feb 2024, 08:01 UTC
0 reputation · 01 Feb 2024, 08:01 UTC
I am designing an Android app that uses AccountManager to obtain an OAuth-style auth token with a narrow scope for a specific account. The goal is to rely on the system for least-privilege credential handling without building custom token storage.
On Android 8.0 (API 26) and later, AccountManager binds returned tokens to the requesting package UID and supports scoped requests. However, documentation does not define a guaranteed token lifetime, and expired tokens reportedly surface as authentication errors rather than triggering automatic refresh. Token expiry appears to depend on the authenticator implementation and can vary by device manufacturer.
Does AccountManager automatically invalidate and replace an expired scoped token when the app requests it again, or must the app call invalidate() and request a new token explicitly? Is the expiration timestamp exposed through AccountManager, or only through the authenticator?
No. Android AccountManager does not automatically refresh an expired scoped auth token; it returns whatever token the authenticator has cached until the app explicitly invalidates it.
AccountManager caches the token returned by the authenticator and re‑uses it for subsequent requests from the same UID/package. It has no built‑in timer to check backend expiry, so the client must detect auth failures (e.g., HTTP 401) and trigger a refresh.
Does your authenticator support silent token refresh via a refresh token or similar mechanism? If it does not, the invalidate‑then‑re‑request flow will prompt the user for re‑authentication.
Use comments to ask for clarification. Post a solution as an answer.
5,040 reputation · 01 Feb 2024, 14:59 UTC
It is important to clarify that AccountManager acts as a proxy rather than an active session manager. It does not possess intrinsic logic to monitor token expiration or automatically trigger refreshes based on server-side TTLs.
Because AccountManager.getToken() typically returns a cached token, the system cannot know a token has expired until the API returns a 401 Unauthorized response. The standard implementation pattern for Android (API 26+) is as follows:
AccountManager.invalidateToken(account, token). This marks the specific token as stale in the system cache.getToken() again. This forces the AccountManager to request a fresh token from the Authenticator.Since expiration timestamps are managed internally by the Authenticator and not exposed via the AccountManager API, this reactive approach is the only reliable way to ensure token validity across different device manufacturers.