Para iniciar sesión con Auth0 en una Capacitor aplicación, cree una Nativo registro una URL de llamada de retorno personalizada como com.example.app://oauth/auth0y ejecutar el flujo de autorización OpenID Connect code con PKCE a través de un navegador del sistema. Con @capgo/capacitor-social-login que es una initialize llamada con tus puntos finales de Auth0 y una SocialLogin.login({ provider: 'oauth2', options: { providerId: 'auth0' } }).
This guide covers the Auth0 dashboard settings, the client code for iOS, Android and web, API access tokens, refresh tokens, logout, and the errors you will run into. It is written for Capacitor 8 as of October 2026.
Cómo funciona el flujo de Auth0 en Capacitor
Auth0 hospeda la página de inicio de sesión (Ingreso Universal). Tu aplicación nunca ve la contraseña. El flujo es:
- La aplicación genera un verificador y un desafío de PKCE, luego abre
https://YOUR_TENANT/authorizeen un navegador seguro. - El usuario inicia sesión (contraseña, social, passkey, MFA, lo que hayas configurado en Auth0).
- Auth0 redirige a tu URL de llamada de retorno con un token de acceso temporal.
code. - La aplicación intercambia el code y el verificador de PKCE en
/oauth/tokenpor un token de identidad, un token de acceso y, opcionalmente, un token de refresco.
El navegador utilizado depende de la plataforma:
| Plataforma | Navegador | Gestión de llamadas de retorno |
|---|---|---|
| iOS | ASWebAuthenticationSession |
Manejado por el sistema, no Info.plist cambio |
| Android | Embedded WebView por defecto, o Chrome Custom Tabs con androidUseCustomTabs: true |
Los Custom Tabs necesitan un filtro de intención |
| Web | Popup (por defecto) o redirección de página completa | handleRedirectCallback() On la página de retorno |
En Android, utilice Custom Tabs. Comparten cookies con Chrome, admiten claves de acceso y administradores de contraseñas, y siguen RFC 8252 (OAuth para aplicaciones nativas), lo que es lo que Auth0 espera.
Paso 1: Configura la aplicación de Auth0
- En el Auth0 Dashboardvea Aplicaciones > Aplicaciones > Crear Aplicación.
- Pick Elige y crearlo.
- y créalo. Sobre la pestaña, tenga en cuenta que Dominio por ejemplo
example.eu.auth0.comy el ID de cliente. - Bajo CredencialesCompruebe que el método de autenticación es Ninguno. Ese es el ajuste de cliente público utilizado con PKCE.
URLs de llamada de retorno y cierre de sesión
Rellene estos campos Configuración > URIs de la aplicación:
| Campo | Valor para móviles | Valor para web |
|---|---|---|
| URLs de llamada permitidas | com.example.app://oauth/auth0 |
https://app.example.com/auth/callback |
| URLs de cierre de sesión permitidas | com.example.app://oauth/logout |
https://app.example.com/ |
| Orígenes web permitidos | No es necesario | https://app.example.com |
Separe múltiples valores con comas. Utilice su Capacitor appId como esquema. Un esquema de dominio inverso evita colisiones con otras aplicaciones. Si también envía una compilación web, muchos equipos crean una aplicación de página única Aplicación de Página Única No mezclan las configuraciones de web y móvil en Auth0 para ello.
Tokens de refresco
Si los usuarios deben permanecer conectados:
- En Configuración > Rotación de tokens de refresco, active la rotación. Cada refresco devuelve un nuevo token de refresco y invalida el antiguo.
- Establezca una vida útil absoluta y de inactividad que se adapte a su producto.
- Si llama a su propio API, abra Apliaciones > APIs > su API > Configuración y habilite Acceso sin conexión.
- Solicite el
offline_accessámbito en la aplicación.
API audiencia
Si su backend valida tokens de acceso de Auth0, cree un API bajo Aplicaciones > APIs con un identificador como https://api.example.com. Pase ese identificador como audienceSin él, el token de acceso solo es válido para Auth0. /userinfo endpoint.
Paso 2: Instale y configure el plugin
bun add @capgo/capacitor-social-login
bunx cap sync
Si Auth0 es tu único proveedor, desactiva los SDK sociales integrados para mantener el tamaño del binario pequeño:
// capacitor.config.ts
plugins: {
SocialLogin: {
providers: { google: false, facebook: false, apple: false, twitter: false },
},
},
filtro de intención de Android para Custom Tabs
Agregue el esquema de llamada a
Agregar el esquema de llamada de retorno MainActivity Inicia android/app/src/main/AndroidManifest.xml:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.example.app" android:host="oauth" />
</intent-filter>
El template de Capacitor ya establece android:launchMode="singleTask" Sobre MainActivity, que necesita el redireccionamiento. Manténlo.
Step 3: Inicia el proveedor de Auth0
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
const AUTH0_DOMAIN = 'https://example.eu.auth0.com';
const isWeb = Capacitor.getPlatform() === 'web';
export async function initAuth() {
await SocialLogin.initialize({
oauth2: {
auth0: {
appId: 'YOUR_AUTH0_CLIENT_ID',
authorizationBaseUrl: `${AUTH0_DOMAIN}/authorize`,
accessTokenEndpoint: `${AUTH0_DOMAIN}/oauth/token`,
resourceUrl: `${AUTH0_DOMAIN}/userinfo`,
redirectUrl: isWeb
? 'https://app.example.com/auth/callback'
: 'com.example.app://oauth/auth0',
scope: 'openid profile email offline_access',
pkceEnabled: true,
additionalParameters: {
audience: 'https://api.example.com',
},
logoutUrl: `${AUTH0_DOMAIN}/oidc/logout`,
postLogoutRedirectUrl: isWeb
? 'https://app.example.com/'
: 'com.example.app://oauth/logout',
androidUseCustomTabs: true,
},
},
});
}
Puedes reemplazar los endpoints explícitos con issuerUrl: AUTH0_DOMAINPuedes reemplazar los puntos finales explícitos con /.well-known/openid-configurationLos valores explícitos ganan sobre los descubiertos, lo que ayuda cuando utilizas un dominio personalizado de Auth0.
Si estás migrando desde Ionic Auth Connect, el plugin también exporta SocialLoginAuthConnect con auth0 preset que toma domain, clientId, redirectUrl and audience. Vease el Guía de migración de Auth Connect.
Step 4: Iniciar sesión
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function signInWithAuth0() {
try {
const { result } = await SocialLogin.login({
provider: 'oauth2',
options: { providerId: 'auth0' },
});
return {
idToken: result.idToken,
accessToken: result.accessToken?.token,
expiresAt: result.accessToken?.expires,
refreshToken: result.refreshToken,
user: result.resourceData, // JSON from /userinfo
};
} catch (error: any) {
if (error?.code === 'USER_CANCELLED') return null;
throw error;
}
}
Opciones de inicio de sesión útiles:
prompt: 'login'Forza la página de inicio de sesión incluso si Auth0 aún tiene una cookie de sesión.loginHint: 'user@example.com'pre-rellena el correo electrónico.additionalParameters: { connection: 'google-oauth2' }omite la autenticación Universal y va directo a una conexión.additionalParameters: { screen_hint: 'signup' }abre la pantalla de registro.
Callback de redirección web
On web, el flujo de popup predeterminado no necesita nada extra. Si utilizas flow: 'redirect'lee el resultado en la página de llamada de vuelta:
const result = await SocialLogin.handleRedirectCallback();
if (result?.provider === 'oauth2') {
console.log(result.result.idToken);
}
handleRedirectCallback es solo para web y rechaza en iOS y Android.
Step 5: Lee el token de ID y llama a tu API
Descodifica el token de ID solo en el cliente para su visualización:
const { claims } = await SocialLogin.decodeIdToken({ idToken: result.idToken! });
console.log(claims.email, claims.name, claims.sub);
decodeIdToken No verifica la firma. Para cualquier cosa relacionada con la seguridad, envía el token de acceso a tu API y validalo allí:
import { createRemoteJWKSet, jwtVerify } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://example.eu.auth0.com/.well-known/jwks.json'));
export async function verifyAuth0AccessToken(token: string) {
const { payload } = await jwtVerify(token, jwks, {
issuer: 'https://example.eu.auth0.com/', // Auth0 issuers end with a slash
audience: 'https://api.example.com',
});
return payload; // payload.sub is the Auth0 user ID
}
Step 6: Refresca el token de acceso
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function getValidAccessToken() {
const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'auth0' });
if (!isLoggedIn) {
// access token expired: try the stored refresh token
try {
await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'auth0' } });
} catch {
// refresh token expired, revoked or already rotated: sign in again
const loginResult = await signInWithAuth0();
if (!loginResult) throw new Error('Sign-in cancelled');
}
}
const { accessToken } = await SocialLogin.getAuthorizationCode({
provider: 'oauth2',
providerId: 'auth0',
});
return accessToken;
}
refresh rechaza cuando el token de refresco ha expirado o ha sido revocado. Con la rotación activada, un token de refresco que ya se ha utilizado también falla, por lo que siempre maneja la rechaza enviando al usuario de nuevo a iniciar sesión.
refresh utiliza el token de refresco que el plugin guardó al iniciar sesión. Si conserva el token de refresco usted mismo, llame SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'auth0', refreshToken })que devuelve la respuesta completa del nuevo token. Con la rotación activada, almacena el nuevo token de refresco cada vez.
El plugin mantiene su copia de token en almacenamiento privado de la aplicación. Si tu revisión de seguridad solicita Keychain o Keystore, almacena el token de refresco con NativeBiometric.setData({ key, value }) de @capgo/capacitor-nativo-biometrique y pasarla a refreshToken tú mismo. Nuestro Guía de almacenamiento de tokens seguros compara las opciones.
Paso 7: Cerrar sesión
await SocialLogin.logout({ provider: 'oauth2', providerId: 'auth0' });
El plugin elimina los tokens almacenados, luego abre logoutUrl with id_token_hint con post_logout_redirect_uri Auth0 elimina su cookie de sesión. /oidc/logout endpoint comprende esos parámetros, y el objetivo de redirección debe estar listado en Permitidos URLs de Cierre de Sesión.
On iOS and Android the end-session page opens in the system browser, so the user briefly leaves the app. If you only want a local logout, omit logoutUrl y pasar prompt: 'login' Para evitar que el usuario se inicie sesión automáticamente en la próxima sesión, establece iosPrefersEphemeralSession: true también evita las cookies compartidas en iOS, a costa de no tener SSO entre aplicaciones.
Solución de problemas
| Error | Causa | Solución |
|---|---|---|
Callback URL mismatch |
URL de redirección no está en las URL de llamada permitidas | Copie el valor exacto de code en la consola, verifique el esquema y el host |
Unauthorized o invalid_client at /oauth/token |
El tipo de aplicación no es nativa, o el método de autenticación no es None | La aplicación no es nativa, o el método de autenticación no es None |
No refreshToken en resultado |
offline_access falta de acceso o API no permite el acceso en modo offline |
Agregar el alcance, habilitar Acceso sin conexión, habilitar rotación |
| no se puede verificar el token de acceso por API | No audience enviado |
Agregar audience en additionalParameters |
| No se reabre la aplicación después de iniciar sesión en Android | El esquema o host del filtro de intención no coincide redirectUrl |
Coincidir com.example.app y oauth exactamente |
OAuth2 provider "auth0" not configured |
login llamado antes initialize o coincidencia de clave |
esperar initialize en el arranque, utilice el mismo providerId |
| la página de cierre permanece abierta | post_logout_redirect_uri no en URLs de cierre permitidas |
agregue, o utilice el cierre local solo |
| error de CORS web en el intercambio de tokens | no en orígenes web permitidos | agregue el origen web, o utilice una aplicación de SPA para web |
Configurar logsEnabled: true imprimir las URL generadas y detalles de intercambio de token en la configuración del proveedor mientras depuras.
Ship auth fixes without a store release
Cambiar ámbitos, el público o el manejo de errores es solo de TypeScript. Con con Capgo actualizaciones en vivo puedes enviar esas correcciones a los usuarios el mismo día. Los cambios nativos, como un nuevo filtro de intención, todavía requieren una nueva versión binaria, que Capgo Construcción Guías relacionadas