Saltar al contenido principal

Usa la IA para integrar Auth0

Si usas un asistente de programación con IA como Claude Code, Cursor o GitHub Copilot, puedes añadir la autenticación de Auth0 automáticamente en cuestión de minutos con agent skills.Primero, instala las agent skills de Auth0:
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-ionic-angular
Después, pídele a tu asistente de IA:
Add Auth0 authentication to my Ionic Angular app
Tu asistente de IA creará automáticamente tu aplicación de Auth0, obtendrá las credenciales, instalará el SDK de Auth0 para Angular y los plugins de Capacitor, configurará el deep linking e implementará flujos de inicio y cierre de sesión con integración con el navegador nativo. Obtén más información sobre Auth0 agent skills.

Primeros pasos

Este inicio rápido muestra cómo agregar la autenticación de Auth0 a una aplicación de Ionic Angular con Capacitor. Crearás una aplicación lista para dispositivos móviles con funciones de Login, cierre de sesión y perfil de usuario mediante el SDK de Auth0 para Angular y los plugins de navegador nativos de Capacitor.
1

Crear un proyecto nuevo

Cree un nuevo proyecto de Ionic Angular con Capacitor
npx ionic start auth0-ionic-angular tabs --type=angular-standalone --capacitor
Abre el proyecto
cd auth0-ionic-angular
Asegúrate de usar el paquete @ionic/cli (no el paquete ionic, que está obsoleto). Si aparece un error relacionado con --npm-client durante la creación del proyecto, actualiza la CLI:
npm uninstall -g ionic
npm i -g @ionic/cli
2

Instala el SDK de Auth0 para Angular y los plugins de Capacitor

Instala el SDK de Auth0 para Angular junto con los complementos Browser y App de Capacitor:
npm install @auth0/auth0-angular @capacitor/browser @capacitor/app
El plugin Browser de Capacitor en iOS usa SFSafariViewController, que en iOS 11+ no comparte cookies con Safari. Esto significa que el SSO no funcionará en esos dispositivos. Si necesita SSO, use un plugin compatible que utilice ASWebAuthenticationSession.
3

Configura tu aplicación en Auth0

A continuación, debes crear una nueva aplicación en tu tenant de Auth0 y agregar las variables de entorno a tu proyecto.Tienes tres opciones para configurar tu aplicación de Auth0: usar la herramienta Quick Setup (recomendado), ejecutar un comando de CLI o configurar manualmente a través del Dashboard:
Crea una aplicación nativa de Auth0 y copia el archivo de entorno rellenado previamente con los valores de configuración correctos.Después de crear la aplicación, actualiza Allowed Callback URLs y Allowed Logout URLs en la pestaña Settings del Auth0 Dashboard. Sustituye YOUR_PACKAGE_ID por el appId de capacitor.config.ts (valor predeterminado: io.ionic.starter):Allowed Callback URLs y Allowed Logout URLs:
YOUR_PACKAGE_ID://{yourDomain}/capacitor/YOUR_PACKAGE_ID/callback
4

Configura el módulo Auth0

Con el archivo de entorno ya creado en el paso anterior, configure el módulo de Auth0 en su aplicación:
src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';
import { provideAuth0 } from '@auth0/auth0-angular';
import { environment } from './environments/environment';
import config from '../capacitor.config';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';

const redirect_uri = `${config.appId}://${environment.auth0.domain}/capacitor/${config.appId}/callback`;

bootstrapApplication(AppComponent, {
  providers: [
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    provideIonicAngular(),
    provideRouter(routes),
    provideAuth0({
      domain: environment.auth0.domain,
      clientId: environment.auth0.clientId,
      useRefreshTokens: true,
      useRefreshTokensFallback: false,
      authorizationParams: {
        redirect_uri,
      },
    }),
  ],
});
La configuración de provideAuth0 incluye:
  • useRefreshTokens: trueobligatorio para móviles. Las aplicaciones de Capacitor no pueden usar autenticación silenciosa basada en iframes, por lo que se usan tokens de actualización para renovar las sesiones.
  • useRefreshTokensFallback: falseobligatorio para móviles. Evita que el SDK recurra a la autenticación silenciosa basada en iframes, que no está disponible en aplicaciones nativas.
  • authorizationParams.redirect_uri — usa el esquema de URL personalizado de tu aplicación para redirigirla de nuevo tras la autenticación.
Para mantener la autenticación después de cerrar y volver a abrir la aplicación, quizá quieras establecer cacheLocation en localstorage, pero ten en cuenta los riesgos de almacenar tokens en localstorage. Además, localstorage debe tratarse como transitorio en las aplicaciones de Capacitor. Consulta la guía sobre almacenamiento en la documentación de Capacitor.
5

Crear componentes de Login, Logout y perfil

Crear los archivos de componentes
touch src/app/login-button.component.ts && touch src/app/logout-button.component.ts && touch src/app/profile.component.ts
Agrega el siguiente código a cada componente:Ahora actualiza el componente App para gestionar los callbacks de Auth0 y la página de inicio para utilizar tus componentes:
Reemplaza el contenido de src/app/app.component.ts:
src/app/app.component.ts
import { Component, OnInit, NgZone, inject } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { mergeMap } from 'rxjs/operators';
import { Browser } from '@capacitor/browser';
import { App } from '@capacitor/app';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
import { environment } from '../environments/environment';
import config from '../../capacitor.config';

const callbackUri = `${config.appId}://${environment.auth0.domain}/capacitor/${config.appId}/callback`;

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [IonApp, IonRouterOutlet],
  template: '<ion-app><ion-router-outlet></ion-router-outlet></ion-app>',
})
export class AppComponent implements OnInit {
  private auth = inject(AuthService);
  private ngZone = inject(NgZone);

  ngOnInit(): void {
    App.addListener('appUrlOpen', ({ url }) => {
      this.ngZone.run(() => {
        if (url?.startsWith(callbackUri)) {
          if (
            url.includes('state=') &&
            (url.includes('error=') || url.includes('code='))
          ) {
            this.auth
              .handleRedirectCallback(url)
              .pipe(mergeMap(() => Browser.close()))
              .subscribe();
          } else {
            Browser.close();
          }
        }
      });
    });
  }
}
El callback del evento appUrlOpen en el componente App está encapsulado en this.ngZone.run(). Esto es necesario porque los callbacks del plugin de Capacitor se ejecutan fuera de la zona de Angular y, sin esto, Angular no detectará los cambios en el estado de autenticación después del inicio de sesión. Consulta Using Angular with Capacitor para obtener más información.
6

Ejecuta tu aplicación

Primero, pruebe en el navegador:
ionic serve
Al ejecutar la aplicación en el navegador con ionic serve, la redirección mediante un esquema de URL personalizado no funcionará porque los navegadores no pueden gestionar este tipo de esquemas. Para hacer pruebas en el navegador, cambie temporalmente redirect_uri a http://localhost:8100 en src/main.ts y añada http://localhost:8100 a Allowed Callback URLs y Allowed Logout URLs de su aplicación de Auth0 en el Dashboard. Recuerde revertir este cambio antes de compilar para un entorno nativo.
Para ejecutarla en un dispositivo o simulador, primero agregue las plataformas nativas:
npx cap add ios
npx cap add android
Luego, compila, sincroniza y ejecuta:
ionic build && npx cap sync && npx cap run ios
Debes añadir las plataformas nativas con npx cap add antes de poder ejecutarlas. Esto solo debe hacerse una vez por plataforma. Asegúrate de que tu esquema de URL personalizado esté registrado (consulta Uso avanzado más abajo).
Punto de controlAhora deberías tener una página de Login de Auth0 totalmente funcional ejecutándose en localhost

Uso avanzado

Si creó su proyecto con --type=angular (en lugar de --type=angular-standalone) o prefiere usar NgModules, configure el SDK con AuthModule.forRoot:
src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AuthModule } from '@auth0/auth0-angular';
import { environment } from '../environments/environment';
import config from '../../capacitor.config';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

const redirect_uri = `${config.appId}://${environment.auth0.domain}/capacitor/${config.appId}/callback`;

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    AuthModule.forRoot({
      domain: environment.auth0.domain,
      clientId: environment.auth0.clientId,
      useRefreshTokens: true,
      useRefreshTokensFallback: false,
      authorizationParams: {
        redirect_uri,
      },
    }),
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}
Al usar NgModules, inyecte AuthService mediante el constructor (constructor(public auth: AuthService)) en lugar de inject(). En las plantillas, use *ngIf="auth.user$ | async as user" en lugar de la sintaxis de control de flujo @if. Los componentes deben declararse en el módulo en lugar de marcarse como standalone: true.
Para probar la autenticación en un dispositivo real, registre su esquema de URL personalizado para cada plataforma.

iOS

Registre su esquema de URL personalizado en ios/App/App/Info.plist:
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>YOUR_PACKAGE_ID</string>
    </array>
  </dict>
</array>
Reemplace YOUR_PACKAGE_ID por su appId de capacitor.config.ts. Para obtener más información, consulte Defining a Custom URL Scheme.

Android

Agregue un filtro de intents a android/app/src/main/AndroidManifest.xml dentro de la etiqueta <activity>:
<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="YOUR_PACKAGE_ID" />
</intent-filter>
Reemplace YOUR_PACKAGE_ID por su appId de capacitor.config.ts. Para obtener más información, consulte Create Deep Links to App Content.

Compilar y ejecutar en un dispositivo

ionic build && npx cap sync && npx cap open ios
O, para Android:
ionic build && npx cap sync && npx cap open android
Usa el guard funcional para proteger las rutas que requieren autenticación:
src/app/app.routes.ts
import { Routes } from '@angular/router';
import { authGuardFn } from '@auth0/auth0-angular';

export const routes: Routes = [
  {
    path: 'tabs',
    loadComponent: () => import('./tabs/tabs.page').then((m) => m.TabsPage),
    children: [
      {
        path: 'tab1',
        loadComponent: () => import('./tab1/tab1.page').then((m) => m.Tab1Page),
      },
      {
        path: 'tab2',
        loadComponent: () => import('./tab2/tab2.page').then((m) => m.Tab2Page),
        canActivate: [authGuardFn],
      },
      {
        path: 'tab3',
        loadComponent: () => import('./tab3/tab3.page').then((m) => m.Tab3Page),
        canActivate: [authGuardFn],
      },
      {
        path: '',
        redirectTo: '/tabs/tab1',
        pathMatch: 'full',
      },
    ],
  },
  {
    path: '',
    redirectTo: '/tabs/tab1',
    pathMatch: 'full',
  },
];
Cuando un usuario no autenticado navega a una ruta protegida, authGuardFn lo redirige automáticamente a la página de inicio de sesión de Auth0.
Configura el interceptor HTTP para adjuntar automáticamente tokens de acceso a las llamadas a la API:
src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideAuth0, authHttpInterceptorFn } from '@auth0/auth0-angular';
import { environment } from './environments/environment';
import config from '../capacitor.config';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';

const redirect_uri = `${config.appId}://${environment.auth0.domain}/capacitor/${config.appId}/callback`;

bootstrapApplication(AppComponent, {
  providers: [
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    provideIonicAngular(),
    provideRouter(routes),
    provideAuth0({
      domain: environment.auth0.domain,
      clientId: environment.auth0.clientId,
      useRefreshTokens: true,
      useRefreshTokensFallback: false,
      authorizationParams: {
        redirect_uri,
        audience: 'YOUR_API_IDENTIFIER',
      },
      httpInterceptor: {
        allowedList: [
          'http://localhost:3001/api/*',
        ],
      },
    }),
    provideHttpClient(
      withInterceptors([authHttpInterceptorFn])
    ),
  ],
});
Luego, haz llamadas a la API con HttpClient de Angular; el interceptor adjunta automáticamente el Bearer Token:
src/app/api.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class ApiService {
  private http = inject(HttpClient);

  getData() {
    return this.http.get('http://localhost:3001/api/data');
  }
}
httpInterceptor.allowedList determina qué endpoints de la API reciben tokens de acceso. Incluye el parámetro audience para solicitar un token de acceso para tu API. Reemplaza YOUR_API_IDENTIFIER por el identificador de Auth0 Dashboard > APIs.

Error de discrepancia en la URL de callback

Solución: Verifica que la URL de callback en tu Auth0 Dashboard coincida exactamente con la URL construida en tu aplicación. Asegúrate de que YOUR_PACKAGE_ID coincida con el campo appId de tu capacitor.config.ts.

La pantalla no se actualiza después del login

Solución: Asegúrate de que el callback del evento appUrlOpen esté envuelto en this.ngZone.run(). De lo contrario, Angular no detectará los cambios de estado de handleRedirectCallback. Consulta Uso de Angular con Capacitor.

Error “PKCE not allowed”

Solución:
  1. Ve a Auth0 Dashboard > Applications > Your Application
  2. Cambia Application Type a Native
  3. Establece Token Endpoint Authentication Method en None
  4. Guarda los cambios y vuelve a intentarlo

SSO no funciona en iOS

El plugin Browser de Capacitor usa SFSafariViewController, que no comparte cookies con Safari en iOS 11+. Si necesitas SSO, usa un plugin compatible que utilice ASWebAuthenticationSession.

Login funciona, pero el usuario sigue sin autenticarse después de reiniciar la aplicación

Habilita cacheLocation: 'localstorage' en la configuración de provideAuth0 para conservar los tokens entre reinicios de la aplicación. Ten en cuenta las implicaciones de seguridad y las limitaciones de almacenamiento de Capacitor.

Un Observable nunca se ejecuta

Todos los métodos de AuthService devuelven Observables fríos. Debes llamar a .subscribe() para que se ejecuten. Si parece que loginWithRedirect() o logout() no hacen nada, verifica que .subscribe() esté encadenado al final.

Próximos pasos

Consulta los siguientes recursos para obtener más información: