Capacitor Preferences persist across APK reinstalls on the same device. A Bearer auth token stored under a global key (e.g., 'ff_auth_token') survives app updates. When the app is rebuilt pointing to a different backend server, the stale token is sent with every request, causing universal 401s — even on public endpoints that don't require auth. The 401 responses trigger CORS preflights (because Authorization is a non-simple header), compounding the problem if CORS middleware ordering is also wrong.
Scope token storage keys by server hostname. Instead of a single global key, use ff_auth_token_{hostname} derived from the current server URL. Include a migration path: read the legacy global key as fallback, then clean it up on next write.
const TOKEN_KEY_PREFIX = 'ff_auth_token';
function _tokenKey(serverUrl?: string): string {
const url = serverUrl || import.meta.env.VITE_FF_API_URL || '';
try {
return `${TOKEN_KEY_PREFIX}_${new URL(url).hostname}`;
} catch {
return TOKEN_KEY_PREFIX;
}
}Also: on mobile, clear the token on ANY 401, not just on 'session expired' signals. Bearer tokens are either valid or not — there's no middle state like cookies have.