A web app keeps a session cookie; a mobile app keeps tokens. A short-lived access token goes with every API request, and a long-lived refresh token buys new access tokens without asking for the password again. How the app gets its first pair is the real choice:
| Approach | Examples | Licence and hosting | Best for |
|---|---|---|---|
| OAuth 2.0 / OpenID Connect provider | Google, Apple, Microsoft | Commercial, free to use | "Sign in with..." buttons |
| Hosted identity service | Auth0 1,168 , Clerk 11,600 , Firebase 1 Auth | Commercial SaaS, MIT SDKs | Teams without an auth server |
| Self-hosted identity server | Keycloak 44,186 , Supabase 5,130 Auth | Apache-2.0, MIT | Control over user data |
| Your own API's password form | Any backend | Yours | Small apps, internal tools |
| Passkeys | Platform APIs via a library | Open standard (WebAuthn) | Phishing-proof sign-in |
Keycloak (Apache-2.0, a CNCF incubating project since April 2023), Supabase Auth, Google and Auth0 all speak OAuth 2.0 and OpenID Connect, so one client library covers them. RFC 8252, OAuth 2.0 for Native Apps, adds two rules: a native app "MUST use an external user-agent" (the system browser, never a WebView the app controls, which could read the password), and a public client "MUST implement" PKCE. A mobile app is public: anything in the APK can be extracted, so it carries a client ID and never a client secret.