auth0-ionic-angular
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAuth0 Ionic Angular (Capacitor) Integration
Auth0 Ionic Angular(Capacitor)集成方案
Add authentication to an Ionic Angular application using the SDK with Capacitor plugins for native iOS and Android. This skill covers login, logout, user profile display, and secure token management using the system browser (SFSafariViewController on iOS, Chrome Custom Tabs on Android) via Capacitor's Browser plugin.
@auth0/auth0-angular借助 SDK和Capacitor插件,为Ionic Angular应用添加认证功能,适配原生iOS和Android平台。本方案涵盖登录、登出、用户资料展示,以及通过Capacitor的Browser插件调用系统浏览器(iOS端为SFSafariViewController,Android端为Chrome Custom Tabs)实现安全的令牌管理。
@auth0/auth0-angularPrerequisites
前置条件
- Node.js 20+ and npm 10+
- Ionic CLI ()
npm install -g @ionic/cli - Capacitor 5+ configured in the project
- Auth0 CLI (for automatic setup):
brew install auth0/auth0-cli/auth0 - An Auth0 account (free tier works)
- Node.js 20+ 及 npm 10+
- Ionic CLI(执行安装)
npm install -g @ionic/cli - 项目中已配置Capacitor 5+
- Auth0 CLI(用于自动配置:)
brew install auth0/auth0-cli/auth0 - 一个Auth0账号(免费版即可)
When NOT to Use
不适用于以下场景
| Use Case | Recommended Skill |
|---|---|
| Ionic React app with Capacitor | |
| Ionic Vue app with Capacitor | |
| Angular SPA (browser-only, no Capacitor) | |
| React Native (no Ionic) | |
| Expo (React Native) | |
| Native iOS (Swift) | |
| Native Android (Kotlin) | |
| 使用场景 | 推荐方案 |
|---|---|
| 搭载Capacitor的Ionic React应用 | |
| 搭载Capacitor的Ionic Vue应用 | |
| Angular单页应用(仅浏览器端,无Capacitor) | |
| React Native(无Ionic) | |
| Expo(React Native) | |
| 原生iOS(Swift) | |
| 原生Android(Kotlin) | |
Quick Start Workflow
快速开始流程
Agent instruction: Follow these steps in order. Always useto let the developer choose between Automatic Setup and Manual Setup before proceeding — even if credentials are already provided in the prompt.AskUserQuestionSECURITY — Never display credentials: After obtaining Auth0 credentials (domain, client ID) via the CLI or from a file, NEVER print, echo, or display them in your text output. Write them directly to the config file () silently. Do NOT produce output like "Domain: xxx" or "Client ID: yyy". Instead, confirm that the config file has been written and tell the user where to find it.src/environments/environment.tsUI reuse: Before creating new login/logout components, search the existing project for login/logout handlers or buttons. If found, hook Auth0 into the existing UI rather than creating duplicate components.
Agent指令: 请按顺序执行以下步骤。无论提示中是否已提供凭证,都必须先使用让开发者选择自动配置还是手动配置,再继续操作。AskUserQuestion安全注意事项——切勿显示凭证: 通过CLI或文件获取Auth0凭证(域名、客户端ID)后,绝对不要在文本输出中打印、回显或展示这些信息。请直接将其静默写入配置文件。不要输出类似“域名:xxx”或“客户端ID:yyy”的内容,只需确认配置文件已写入,并告知用户文件位置即可。src/environments/environment.tsUI复用: 在创建新的登录/登出组件前,请先搜索现有项目中是否存在登录/登出处理器或按钮。如果存在,请将Auth0集成到现有UI中,避免创建重复组件。
Step 1: Install Dependencies
步骤1:安装依赖
bash
npm install @auth0/auth0-angular @capacitor/browser @capacitor/appbash
npm install @auth0/auth0-angular @capacitor/browser @capacitor/appStep 2: Configure Auth0
步骤2:配置Auth0
Agent instruction: Always present the setup choice using— even if the user has already provided credentials:AskUserQuestionAskUserQuestion: question: "How would you like to configure Auth0 for your Ionic Angular app?" options: - label: "Automatic Setup (Recommended)" description: "Uses the Auth0 CLI to create a Native application, configure callback URLs, and store credentials in your project automatically." - label: "Manual Setup" description: "You provide an .env file with your Auth0 Domain and Client ID, and the agent reads it and writes the project configuration for you."Follow the chosen path in the Setup Guide which has the full step-by-step instructions for both options.
Auth0 Dashboard settings (Native application type):
| Setting | Value |
|---|---|
| Application Type | Native |
| Allowed Callback URLs | |
| Allowed Logout URLs | |
| Allowed Origins | |
Replace with your from (e.g., ) and with your Auth0 domain.
PACKAGE_IDappIdcapacitor.config.tscom.example.myappYOUR_DOMAINNote: For Automatic Setup, these URLs are configured automatically by the Auth0 CLI. For Manual Setup, the user must configure them in the Auth0 Dashboard.
Note: For local web development (), also addionic serveto Allowed Callback URLs, Allowed Logout URLs, and Allowed Web Origins.http://localhost:8100
Agent指令: 无论用户是否已提供凭证,都必须通过提供配置选项:AskUserQuestionAskUserQuestion: question: "您希望如何为Ionic Angular应用配置Auth0?" options: - label: "自动配置(推荐)" description: "使用Auth0 CLI创建Native应用、配置回调URL,并自动将凭证存储到项目中。" - label: "手动配置" description: "您提供包含Auth0域名和客户端ID的.env文件,Agent会读取并写入项目配置。"根据选择的方式,遵循配置指南中的完整分步说明操作。
Auth0控制台设置(Native应用类型):
| 设置项 | 值 |
|---|---|
| 应用类型 | Native |
| 允许的回调URL | |
| 允许的登出URL | |
| 允许的源 | |
将替换为中的(例如),替换为您的Auth0域名。
PACKAGE_IDcapacitor.config.tsappIdcom.example.myappYOUR_DOMAIN注意: 自动配置时,这些URL会由Auth0 CLI自动配置。手动配置时,用户必须在Auth0控制台中完成配置。
注意: 对于本地Web开发(),还需将ionic serve添加到允许的回调URL、允许的登出URL和允许的Web源中。http://localhost:8100
Step 3: Configure the SDK
步骤3:配置SDK
In (NgModule) or (standalone):
src/app/app.module.tssrc/app/app.config.tsThe function (or ) is the Angular equivalent of — it acts as the provider/wrapper that wraps the app and makes available everywhere. For local web development with , the callback URL is .
provideAuth0()AuthModule.forRoot()Auth0ProviderAuthServiceionic servehttp://localhost:8100Standalone (Angular 17+):
typescript
import { ApplicationConfig } from '@angular/core';
import { provideAuth0 } from '@auth0/auth0-angular';
// Replace with your capacitor.config.ts appId and Auth0 domain
const appId = 'com.example.myapp';
const domain = 'YOUR_AUTH0_DOMAIN';
const callbackUri = `${appId}://${domain}/capacitor/${appId}/callback`;
export const appConfig: ApplicationConfig = {
providers: [
provideAuth0({
domain,
clientId: 'YOUR_AUTH0_CLIENT_ID',
useRefreshTokens: true,
useRefreshTokensFallback: false,
authorizationParams: {
redirect_uri: callbackUri,
},
}),
],
};NgModule (Angular 16 and earlier):
typescript
import { AuthModule } from '@auth0/auth0-angular';
const appId = 'com.example.myapp';
const domain = 'YOUR_AUTH0_DOMAIN';
const callbackUri = `${appId}://${domain}/capacitor/${appId}/callback`;
@NgModule({
imports: [
AuthModule.forRoot({
domain,
clientId: 'YOUR_AUTH0_CLIENT_ID',
useRefreshTokens: true,
useRefreshTokensFallback: false,
authorizationParams: {
redirect_uri: callbackUri,
},
}),
],
})
export class AppModule {}在(NgModule模式)或(独立组件模式)中配置:
src/app/app.module.tssrc/app/app.config.tsprovideAuth0()AuthModule.forRoot()Auth0ProviderAuthServiceionic servehttp://localhost:8100独立组件模式(Angular 17+):
typescript
import { ApplicationConfig } from '@angular/core';
import { provideAuth0 } from '@auth0/auth0-angular';
// 替换为您的capacitor.config.ts中的appId和Auth0域名
const appId = 'com.example.myapp';
const domain = 'YOUR_AUTH0_DOMAIN';
const callbackUri = `${appId}://${domain}/capacitor/${appId}/callback`;
export const appConfig: ApplicationConfig = {
providers: [
provideAuth0({
domain,
clientId: 'YOUR_AUTH0_CLIENT_ID',
useRefreshTokens: true,
useRefreshTokensFallback: false,
authorizationParams: {
redirect_uri: callbackUri,
},
}),
],
};NgModule模式(Angular 16及更早版本):
typescript
import { AuthModule } from '@auth0/auth0-angular';
const appId = 'com.example.myapp';
const domain = 'YOUR_AUTH0_DOMAIN';
const callbackUri = `${appId}://${domain}/capacitor/${appId}/callback`;
@NgModule({
imports: [
AuthModule.forRoot({
domain,
clientId: 'YOUR_AUTH0_CLIENT_ID',
useRefreshTokens: true,
useRefreshTokensFallback: false,
authorizationParams: {
redirect_uri: callbackUri,
},
}),
],
})
export class AppModule {}Step 4: Handle Deep Link Callbacks (AppComponent)
步骤4:处理深度链接回调(AppComponent)
Register the listener at the app root so it persists across navigation:
appUrlOpentypescript
import { Component, NgZone, OnInit } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
import { App as CapApp } from '@capacitor/app';
import { mergeMap } from 'rxjs/operators';
@Component({
selector: 'app-root',
template: `<ion-app><ion-router-outlet></ion-router-outlet></ion-app>`,
})
export class AppComponent implements OnInit {
constructor(
private auth: AuthService,
private ngZone: NgZone
) {}
ngOnInit() {
CapApp.addListener('appUrlOpen', ({ url }) => {
this.ngZone.run(() => {
if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
this.auth
.handleRedirectCallback(url)
.pipe(mergeMap(() => Browser.close()))
.subscribe();
}
});
});
}
}在应用根节点注册监听器,使其在导航过程中持续生效:
appUrlOpentypescript
import { Component, NgZone, OnInit } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
import { App as CapApp } from '@capacitor/app';
import { mergeMap } from 'rxjs/operators';
@Component({
selector: 'app-root',
template: `<ion-app><ion-router-outlet></ion-router-outlet></ion-app>`,
})
export class AppComponent implements OnInit {
constructor(
private auth: AuthService,
private ngZone: NgZone
) {}
ngOnInit() {
CapApp.addListener('appUrlOpen', ({ url }) => {
this.ngZone.run(() => {
if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
this.auth
.handleRedirectCallback(url)
.pipe(mergeMap(() => Browser.close()))
.subscribe();
}
});
});
}
}Step 5: Implement Login
步骤5:实现登录功能
typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
@Component({
selector: 'app-login',
template: `<ion-button (click)="login()">Log In</ion-button>`,
})
export class LoginPage {
constructor(public auth: AuthService) {}
login() {
this.auth
.loginWithRedirect({
async openUrl(url: string) {
await Browser.open({ url, windowName: '_self' });
},
})
.subscribe();
}
}typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
@Component({
selector: 'app-login',
template: `<ion-button (click)="login()">登录</ion-button>`,
})
export class LoginPage {
constructor(public auth: AuthService) {}
login() {
this.auth
.loginWithRedirect({
async openUrl(url: string) {
await Browser.open({ url, windowName: '_self' });
},
})
.subscribe();
}
}Step 6: Implement Logout
步骤6:实现登出功能
typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
@Component({
selector: 'app-logout-button',
template: `<ion-button (click)="logout()">Log Out</ion-button>`,
})
export class LogoutButtonComponent {
constructor(public auth: AuthService) {}
logout() {
this.auth
.logout({
logoutParams: {
returnTo: `YOUR_PACKAGE_ID://YOUR_AUTH0_DOMAIN/capacitor/YOUR_PACKAGE_ID/callback`,
},
async openUrl(url: string) {
await Browser.open({ url, windowName: '_self' });
},
})
.subscribe();
}
}typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { Browser } from '@capacitor/browser';
@Component({
selector: 'app-logout-button',
template: `<ion-button (click)="logout()">登出</ion-button>`,
})
export class LogoutButtonComponent {
constructor(public auth: AuthService) {}
logout() {
this.auth
.logout({
logoutParams: {
returnTo: `YOUR_PACKAGE_ID://YOUR_AUTH0_DOMAIN/capacitor/YOUR_PACKAGE_ID/callback`,
},
async openUrl(url: string) {
await Browser.open({ url, windowName: '_self' });
},
})
.subscribe();
}
}Step 7: Display User Profile
步骤7:展示用户资料
typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'app-profile',
template: `
<div *ngIf="auth.user$ | async as user">
<img [src]="user.picture" [alt]="user.name" />
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
`,
})
export class ProfileComponent {
constructor(public auth: AuthService) {}
}typescript
import { Component } from '@angular/core';
import { AuthService } from '@auth0/auth0-angular';
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'app-profile',
template: `
<div *ngIf="auth.user$ | async as user">
<img [src]="user.picture" [alt]="user.name" />
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
`,
})
export class ProfileComponent {
constructor(public auth: AuthService) {}
}Step 8: Build and Test
步骤8:构建并测试
Agent instruction: After writing all code, verify the build succeeds:bashnpm run build npx cap syncIf the build fails, investigate errors and fix (up to 5-6 iterations). If still failing, useto ask the user for help.AskUserQuestion
Agent指令: 编写完所有代码后,验证构建是否成功:bashnpm run build npx cap sync如果构建失败,请排查错误并修复(最多尝试5-6次)。若仍失败,请使用向用户寻求帮助。AskUserQuestion
Detailed Documentation
详细文档
- Setup Guide — Auth0 configuration, Auth0 CLI setup, Capacitor platform setup, deep linking
- Integration Patterns — Login/logout flows, token management, user profile, error handling, Capacitor lifecycle
- API Reference & Testing — AuthService API, configuration options, claims reference, testing checklist
- 配置指南 — Auth0配置、Auth0 CLI设置、Capacitor平台设置、深度链接
- 集成模式 — 登录/登出流程、令牌管理、用户资料、错误处理、Capacitor生命周期
- API参考与测试 — AuthService API、配置选项、声明参考、测试清单
Common Mistakes
常见错误
| Mistake | Fix |
|---|---|
| Auth0 app type set to SPA instead of Native | Change to Native in Auth0 Dashboard → Application Settings |
| Missing callback URL in Auth0 Dashboard | Add |
Not wrapping | Angular won't detect auth state changes — always wrap in |
Using | Must use |
| Required for mobile — localStorage is unreliable on native platforms |
| Must be |
Missing | The |
Using | Popups don't work on native — use |
| Callback URL mismatch (scheme vs package ID) | The URL scheme must match the |
| 错误 | 修复方案 |
|---|---|
| Auth0应用类型设置为SPA而非Native | 在Auth0控制台→应用设置中修改为Native |
| Auth0控制台中缺少回调URL | 将 |
未将 | Angular无法检测认证状态变化——必须始终包裹在 |
使用 | 必须使用 |
| 移动端必须开启——localStorage在原生平台不可靠 |
| 必须设为 |
缺少 | |
在移动端使用 | 弹窗在原生平台无法工作——使用 |
| 回调URL不匹配(协议与包ID不一致) | URL协议必须与 |
WebAuth Method
WebAuth认证方式
Ionic with Capacitor uses the Web Auth method for authentication:
- User taps Log In → app calls with a custom
loginWithRedirectthat usesopenUrlBrowser.open() - Capacitor's Browser plugin opens the Auth0 Universal Login page in the system browser (SFSafariViewController / Chrome Custom Tabs)
- User authenticates → Auth0 redirects to the custom URL scheme callback
- OS routes the deep link to your app → event fires
appUrlOpen - processes the auth code exchange inside
handleRedirectCallback(url)ngZone.run() - dismisses the system browser
Browser.close() - emits
auth.isAuthenticated$, andtrueemits the user profileauth.user$
搭载Capacitor的Ionic应用使用Web Auth方式进行认证:
- 用户点击登录→应用调用,并传入自定义
loginWithRedirect,该方法使用openUrlBrowser.open() - Capacitor的Browser插件在系统浏览器(SFSafariViewController / Chrome Custom Tabs)中打开Auth0通用登录页面
- 用户完成认证→Auth0重定向到自定义URL协议的回调地址
- 操作系统将深度链接路由到您的应用→触发事件
appUrlOpen - 在
handleRedirectCallback(url)中处理授权码交换ngZone.run() - 关闭系统浏览器
Browser.close() - 发出
auth.isAuthenticated$,true发出用户资料auth.user$
Related Skills
相关方案
- auth0-ionic-react — Ionic React with Capacitor
- auth0-ionic-vue — Ionic Vue with Capacitor
- auth0-angular — Angular SPA (browser-only)
- auth0-swift — Native iOS (Swift)
- auth0-android — Native Android (Kotlin)
- auth0-ionic-react — 搭载Capacitor的Ionic React应用
- auth0-ionic-vue — 搭载Capacitor的Ionic Vue应用
- auth0-angular — Angular单页应用(仅浏览器端)
- auth0-swift — 原生iOS(Swift)应用
- auth0-android — 原生Android(Kotlin)应用
Quick Reference
快速参考
| API | Description |
|---|---|
| Start login flow with custom |
| Log out with custom |
| Process the callback URL from the deep link |
| Observable boolean — whether user is logged in |
| Observable — current user profile (name, email, picture) |
| Observable boolean — SDK initialization state |
| Observable — authentication errors |
| Get access token (uses refresh tokens on mobile) |
| Open URL in system browser (Capacitor) |
| Listen for deep link callbacks (Capacitor) |
| API | 描述 |
|---|---|
| 启动登录流程,为Capacitor传入自定义 |
| 执行登出操作,传入自定义 |
| 处理深度链接中的回调URL |
| 可观察布尔值——表示用户是否已登录 |
| 可观察对象——当前用户资料(姓名、邮箱、头像) |
| 可观察布尔值——SDK初始化状态 |
| 可观察对象——认证错误信息 |
| 获取访问令牌(移动端使用刷新令牌) |
| 在系统浏览器中打开URL(Capacitor) |
| 监听深度链接回调(Capacitor) |