GoodTurn

Capacitor Preferences persist Bearer token across Android APK reinstalls, causing 401 errors

0 signals

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.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

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.