Saltar al contenido principal
Guías Seguridad Capacitor

Cómo añadir autenticación a una app Capacitor (2026)

Compara todas las formas de añadir autenticación a una app de Capacitor: login nativo de Google/Apple, OIDC SSO, Firebase, Supabase, Neon, Better Auth, passkeys y biometría.

Cómo añadir autenticación a una app Capacitor (2026)

Para añadir autenticación a una app de Capacitor, elige una fuente de identidad (tu propio backend, un servicio como Firebase, Supabase o Neon, un proveedor OIDC como Auth0, Okta o Entra ID, o una librería self-hosted como Better Auth), usa plugins nativos para abrir la página de login del proveedor, verifica los tokens en un servidor y guarda la sesión resultante en el Keychain o Keystore. La biometría y las passkeys harán que el siguiente inicio de sesión sea instantáneo.

Esta guía vincula cada opción común con el plugin y flujo de Capacitor adecuado, con code para los procesos estándar: la llamada de login, verificación de tokens, almacenamiento de sesión y desbloqueo biométrico. Actualizado para Capacitor 8 en octubre de 2026. Cada proveedor tiene su propia guía paso a paso enlazada abajo.

El flujo de auth con el que termina toda app de Capacitor

Sin importar el provider que elijas, la estructura es la misma:

  1. Identificar al usuario: mediante el sheet social nativo, la página de login del provider en el browser, un prompt de passkey o un formulario de email y password.
  2. Obtener una prueba: un ID token, un code de autorización o un session token de tu servidor de auth.
  3. Verificar en el servidor: validar firma, issuer, audience y expiry, y luego crear o buscar al usuario.
  4. Emitir una sesión: tu propio token o los tokens del provider, con una estrategia de refresh.
  5. Almacenarlo de forma segura en el dispositivo y adjuntarlo a las llamadas de API.
  6. Desbloqueo rápido la próxima vez con biometría, y gestiona el logout y la eliminación de cuentas.

Los pasos 1 y 2 varían según el proveedor. Los pasos 3 al 6 son tu responsabilidad en todas las opciones, excepto en BaaS totalmente gestionado, donde SDK hace casi todo.

Por qué fallan las páginas de login en WebView

Una app Capacitor ejecuta tu code web en un WKWebView (iOS) o Android WebView con un origen local (capacitor://localhost o https://localhost). Cargar la página de login de un proveedor dentro de ese WebView causa tres problemas:

  • Google devuelve disallowed_useragent y se niega a mostrar la página.
  • La app no puede demostrar que la página es el proveedor real, por eso RFC 8252 indica que las apps nativas usen el navegador del sistema.
  • Un redirect a pantalla completa te saca de tu app bundled y hace que pierdas el estado.

Por eso, cada flujo a continuación usa un SDK nativo (Apple, Google, Facebook) o una sesión de navegador del sistema (ASWebAuthenticationSession en iOS, Chrome Custom Tabs en Android) que regresa a la app mediante un custom scheme.

Tus opciones de un vistazo

Enfoque Ideal para plugin Capacitor Trabajo de backend Guía
Iniciar sesión con Apple Cualquier app de iOS con login de terceros @capgo/capacitor-social-login Verificar el ID token Guía de Apple
Inicio de sesión con Google Apps de consumo, Android primero @capgo/capacitor-social-login Verificar ID token Guía de Google
Auth0 Login alojado con múltiples conexiones @capgo/capacitor-social-login (OAuth2) Validar access tokens Guía de Auth0
Okta Workforce y SSO B2B @capgo/capacitor-social-login (OAuth2) Validar access tokens Guía de Okta
Microsoft Entra ID Organizaciones de Microsoft 365 @capgo/capacitor-social-login (OAuth2) Validar access tokens, Graph Guía de Entra ID
Mejor autenticación Self-hosted, base de datos propia better-auth cliente + Social Login Ejecutar el servidor Better Auth Guía de Better Auth
Autenticación de Supabase Backend Postgres con auth integrada Social Login + supabase-js Mínimo Guía de Supabase
Neon Auth Neon Postgres con Better Auth gestionado @capgo/capacitor-neon Mínimo Docs del plugin de Neon
Autenticación de Firebase Apps que ya usan Firebase @capgo/capacitor-firebase-authentication Mínimo Docs de Firebase
Passkeys Login sin contraseña en tu propio dominio @capgo/capacitor-passkey Servidor WebAuthn Docs de Passkeys
Email y contraseña Apps simples, backend propio Ninguno (HTTP) Hashing, restablecimiento y rate limits Este artículo

Social sign-in nativo (Apple, Google, Facebook)

Un plugin cubre los tres grandes proveedores más un motor OAuth2 genérico:

bun add @capgo/capacitor-social-login
bunx cap sync
import { SocialLogin } from '@capgo/capacitor-social-login';

await SocialLogin.initialize({
  apple: { clientId: 'com.example.app' },
  google: {
    webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com',
    iOSClientId: 'IOS_CLIENT_ID.apps.googleusercontent.com',
  },
});

const { result } = await SocialLogin.login({ provider: 'google', options: {} });
// send result.idToken to your server

Desactiva los providers que no uses en capacitor.config.ts (plugins.SocialLogin.providers) para que sus SDKs no se compilen en la app. Esto también elimina el permiso del ID de publicidad de Facebook SDK si no usas Facebook.

Cada proveedor requiere una configuración nativa: Apple necesita la capability en Xcode y un Services ID; para Android, Google requiere fingerprints SHA-1 y un esquema de URL de client ID invertido. Las Apple y Google guías detallan cada paso y los errores comunes.

SSO empresarial con OAuth 2.0 y OpenID Connect

Para Auth0, Okta, Microsoft Entra ID, Keycloak, Cognito, OneLogin o tu propio servidor OIDC, usa el oauth2 provider del plugin. Este ejecuta el flujo de autorización code con PKCE en ASWebAuthenticationSession en iOS y en Custom Tabs en Android cuando configuras androidUseCustomTabs: true:

await SocialLogin.initialize({
  oauth2: {
    corp: {
      issuerUrl: 'https://sso.example.com/realms/mobile', // OIDC discovery
      clientId: 'mobile-app',
      redirectUrl: 'com.example.app://oauth/corp',
      scope: 'openid profile email offline_access',
      pkceEnabled: true,
      androidUseCustomTabs: true,
    },
  },
});

const { result } = await SocialLogin.login({
  provider: 'oauth2',
  options: { providerId: 'corp' },
});

Puedes registrar varios providers en el mismo map y elegir uno con providerId, que es como las apps B2B multi-tenant permiten que cada cliente use su propio IdP. El plugin también gestiona el refresh (SocialLogin.refresh), cerrar sesión con id_token_hint, y un wrapper compatible con Ionic Auth Connect (SocialLoginAuthConnect) para equipos que migran desde Auth Connect. Guías de proveedores: Auth0, Okta, Entra ID. Para entender el protocolo, consulta 5 pasos para implementar OAuth2 en apps Capacitor.

Backends gestionados: Firebase, Supabase y Neon

Si tus datos ya están en Firebase, Supabase o Neon, usa su auth para que las security rules y el row-level security funcionen sin código extra.

  • Supabase: obtén un ID token con el plugin Social Login y llama supabase.auth.signInWithIdToken({ provider: 'google', token }). Supabase lo verifica y devuelve una sesión. Configuración completa: Supabase con Capacitor Social Login.
  • Neon: Neon Auth es un Better Auth gestionado que reside en tu rama de Neon. @capgo/capacitor-neon inicia sesión de forma nativa con email y contraseña, OTP por email, Google, GitHub o Vercel OAuth en el navegador del sistema. Devuelve un JWT para el Datos de Neon API, so row-level security applies. Full setup: docs del plugin de Neon.
  • Firebase: puedes usar @capgo/capacitor-firebase-authentication, que envuelve los SDK nativos de Firebase Auth, o bien obtener un ID token con Social Login y crear una credencial de Firebase desde el SDK de JS. Consulta la Docs de Google login de Firebase.

Self-hosted: Better Auth

Better Auth es una librería de auth open-source en TypeScript que almacena usuarios en tu propia base de datos. Funciona en Capacitor una vez que confíes en los orígenes de la app y cambies a bearer tokens, ya que las cookies cross-site no son fiables en WKWebView. El social login se gestiona mediante el plugin nativo y un handoff de ID token. Paso a paso: Cómo usar Better Auth en apps de Capacitor.

Passkeys

Las passkeys reemplazan las contraseñas con un par de llaves guardado en iCloud Keychain o Google Password Manager. Requieren que tu app esté asociada a tu dominio web (apple-app-site-association en iOS, assetlinks.json en Android) y a un servidor WebAuthn.

@capgo/capacitor-passkey te permite mantener el code estándar de WebAuthn. Configura el relying party en capacitor.config.ts, llama al shim una vez al inicio, y navigator.credentials.create() y .get() se redirigen a las APIs nativas de passkeys:

import { CapacitorPasskey } from '@capgo/capacitor-passkey';

await CapacitorPasskey.autoShimWebAuthn();

// existing WebAuthn code keeps working
const assertion = await navigator.credentials.get({
  publicKey: requestOptionsFromServer,
});

Librerías como Better Auth, y proveedores gestionados como Auth0 y Okta, pueden actuar como el servidor WebAuthn. Consulta la página del plugin passkey.

Email y contraseña con tu propio backend

No necesitas ningún plugin, es simplemente fetch. El trabajo se hace en el servidor: hash con Argon2id o bcrypt, rate-limit en intentos de login, envío de emails de verificación y reset, y soporte para borrado de cuenta. Abre los links de reset y verificación en la app con Universal Links y App Links para que el link llegue al lugar correcto en el móvil. A menos que necesites control total, una librería como Better Auth o un servicio gestionado te da las mismas funciones con menos riesgo.

Verifica siempre los tokens en el servidor

Las validaciones en el cliente se pueden saltar. Sea cual sea el proveedor, el servidor debe verificar el token antes de crear una sesión:

import { createRemoteJWKSet, jwtVerify } from 'jose';

type IssuerConfig = {
  jwks: ReturnType<typeof createRemoteJWKSet>;
  issuer: string | string[];
  audience: string[];
};

const issuers: Record<'google' | 'apple', IssuerConfig> = {
  google: {
    jwks: createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs')),
    issuer: ['https://accounts.google.com', 'accounts.google.com'],
    audience: ['WEB_CLIENT_ID.apps.googleusercontent.com', 'IOS_CLIENT_ID.apps.googleusercontent.com'],
  },
  apple: {
    jwks: createRemoteJWKSet(new URL('https://appleid.apple.com/auth/keys')),
    issuer: 'https://appleid.apple.com',
    audience: ['com.example.app', 'com.example.app.signin'],
  },
};

export async function verifyIdToken(provider: 'google' | 'apple', idToken: string) {
  const cfg = issuers[provider];
  const { payload } = await jwtVerify(idToken, cfg.jwks, {
    issuer: cfg.issuer,
    audience: cfg.audience,
  });
  return payload; // use payload.sub as the stable provider user ID
}

Usuarios clave en el sub (más el nombre del proveedor), no por email. Solo vincula cuentas por email cuando el proveedor lo marque como verificado ("email_verified: true"). Los tokens de Limited Login de Meta no incluyen ese claim.

Almacena la sesión de forma segura

localStorage y las Capacitor Preferences son archivos simples. Guarda tokens de larga duración en el Keychain (iOS) o en un almacenamiento cifrado con Keystore (Android). @capgo/capacitor-native-biometric tiene métodos setData, getData y deleteData sencillos para ello:

bun add @capgo/capacitor-native-biometric
bunx cap sync
import { NativeBiometric } from '@capgo/capacitor-native-biometric';

export const sessionStore = {
  async save(token: string) {
    await NativeBiometric.setData({ key: 'session.token', value: token });
  },
  async load(): Promise<string | null> {
    try {
      const { value } = await NativeBiometric.getData({ key: 'session.token' });
      return value;
    } catch {
      return null;
    }
  },
  async clear() {
    await NativeBiometric.deleteData({ key: 'session.token' }).catch(() => {});
  },
};

Mantén los access tokens con vida corta y renuévalos con un refresh token o una sesión en el servidor. Nuestra guía de almacenamiento seguro de tokens explica la rotación y revocación en detalle.

Biometría: desbloqueo, no identidad

Face ID y la huella digital solo prueban que quien tiene el teléfono puede desbloquearlo. Úsalos para controlar el acceso a una sesión guardada:

import { AccessControl, NativeBiometric } from '@capgo/capacitor-native-biometric';

// after a real login, offer biometric unlock
await NativeBiometric.setData({
  key: 'session.refresh',
  value: refreshToken,
  accessControl: AccessControl.BIOMETRY_ANY,
});

// next app start
const { value } = await NativeBiometric.getSecureData({
  key: 'session.refresh',
  reason: 'Unlock your account',
});
// exchange `value` with your server for a fresh access token

Con accessControl una vez establecido, el SO libera el valor solo tras un check biométrico exitoso; así, la protección la aplica el Keychain o Keystore, no JavaScript. Combínalo con expiración de sesión en el servidor y, en apps de alto riesgo, detección de root y jailbreak. Más en Autenticación biométrica en apps de Capacitor.

Elegir un método

Si tú... Usa
Lanzas una app de consumo en iOS y Android Apple + Google mediante Social Login, además de email o passkeys
Vendes a empresas que usan Microsoft 365 Entra ID mediante un proveedor OAuth2
Necesitas muchos IdPs empresariales por cliente Auth0 u Okta como broker, o varios proveedores OAuth2 providerId
Ya usas Supabase o Firebase Su auth con inicio de sesión mediante native ID token
Ya usas Neon Neon Auth a través de @capgo/capacitor-neon
¿Quieres tu propia tabla de usuarios sin proveedores? Mejor autenticación
¿Buscas un login sin contraseña? Passkeys, con un fallback como magic links por email
¿Necesitas un re-login rápido? Desbloqueo biométrico de una sesión almacenada, además de cualquiera de las opciones anteriores

Reglas de App Store y Play que afectan al login

  • Servicios de inicio de sesión de Apple 4.8: si el login de terceros es el sistema principal, requiere una opción equivalente centrada en la privacidad. Sign in with Apple lo cumple.
  • Apple 5.1.1(v): la creación de cuentas exige la eliminación de la cuenta en la app, y los tokens de Sign in with Apple deben revocarse. Ver cumplimiento de eliminación de cuentas.
  • Eliminación de cuentas en Google Play: las apps con cuentas deben ofrecer la opción de borrado en la app y mediante un enlace web declarado en Play Console.
  • Acceso para revisores: proporciona a los revisores una cuenta de demo funcional. Si el login es solo SSO, ofrece un usuario de prueba.
  • Xcode 26: App Store Connect requiere builds hechas con Xcode 26 y el SDK de iOS 26 desde abril de 2026; actualiza antes de enviar un release con nuevas funciones de auth.

Lanza cambios de auth de forma segura

Los bugs de auth bloquean a todos los usuarios, así que hay que arreglarlos rápido. Los cambios nativos (entitlements, URL schemes, intent filters) requieren un build de la store. Todo en TypeScript, como la config del provider, scopes, manejo de errores y UI, se puede enviar con actualizaciones Live Update de Capgo y se revierte si algo falla. Build de Capgo genera los binarios firmados de iOS y Android en la nube cuando necesites un nuevo release nativo.

Próximos pasos

Elige tu proveedor y sigue su guía correspondiente:

Live updates para apps Capacitor

Cuando un bug de la capa web está en producción, publica el fix a través de Capgo en lugar de esperar días a la aprobación de la app store. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen el flujo de revisión habitual.

Lo último de nuestro blog

Capgo te da la información clave que necesitas para crear una app móvil realmente profesional.