关于 auth0-ionic-angular
为使用 Capacitor 的 Ionic Angular 应用提供 Auth0 原生移动端认证集成指导,涵盖登录、登出、用户资料和令牌管理。流程使用系统浏览器及深度链接处理认证回调。
主要功能
- 01集成 Auth0 Angular SDK
- 02通过系统浏览器登录和登出
- 03处理深度链接认证回调
- 04获取用户资料与访问令牌
- 05指导自动或手动配置
适用场景
- 01为 Ionic Angular 移动应用添加登录
- 02处理 iOS 和 Android 的认证回调
- 03显示用户资料并管理令牌
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ auth0/ agent-skills --skill auth0-ionic-angular安装后在 Claude Code 中输入/auth0-ionic-angular确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api.mdintegration.mdsetup.mdtests/benchmark-config.jsonevals.jsongraders.jsongraders.tspackage.jsonprompt.mdrun-evals.mjs详细介绍
Auth0 Ionic Angular(Capacitor)集成
使用 @auth0/auth0-angular SDK 和 Capacitor 插件,为 Ionic Angular 应用添加身份验证,支持原生 iOS 和 Android。此技能涵盖登录、登出、用户个人资料显示,以及通过 Capacitor 的 Browser 插件使用系统浏览器(iOS 上的 SFSafariViewController,Android 上的 Chrome Custom Tabs)安全管理令牌。
前提条件
- Node.js 20+ 和 npm 10+
- Ionic CLI(
npm install -g @ionic/cli) - 项目中已配置 Capacitor 5+
- Auth0 CLI(用于自动设置):
brew install auth0/auth0-cli/auth0 - Auth0 账户(免费套餐即可)
不适用场景
| 使用场景 | 推荐技能 |
|---|---|
| 使用 Capacitor 的 Ionic React 应用 | auth0-ionic-react |
| 使用 Capacitor 的 Ionic Vue 应用 | auth0-ionic-vue |
| Angular SPA(仅限浏览器,不使用 Capacitor) | auth0-angular 或 auth0-react |
| React Native(不使用 Ionic) | auth0-react-native |
| Expo(React Native) | auth0-expo |
| 原生 iOS(Swift) | auth0-swift |
| 原生 Android(Kotlin) | auth0-android |
快速入门工作流
Agent 指令: 按顺序执行以下步骤。继续操作之前,务必使用
AskUserQuestion让开发者在自动设置和手动设置之间进行选择,即使提示中已提供凭据也不例外。安全 — 切勿显示凭据: 通过 CLI 获取 Auth0 凭据(domain、client ID)或从文件读取后,切勿在文本输出中打印、回显或显示这些凭据。直接将其静默写入配置文件(
src/environments/environment.ts)。不要输出类似“域名:xxx”或“客户端 ID:yyy”的内容。应确认配置文件已写入,并告知用户在哪里可以找到该文件。复用 UI: 创建新的登录/登出组件之前,先在现有项目中查找登录/登出处理器或按钮。如果找到,应将 Auth0 接入现有 UI,而不是创建重复组件。
步骤 1:安装依赖项
npm install @auth0/auth0-angular @capacitor/browser @capacitor/app
步骤 2:配置 Auth0
Agent 指令: 务必使用
AskUserQuestion提供设置选项,即使用户已提供凭据也不例外:AskUserQuestion: 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."按照所选方式完成设置指南,其中包含两种选项的完整分步说明。
Auth0 Dashboard 设置(Native 应用类型):
| 设置项 | 值 |
|---|---|
| 应用类型 | Native |
| 允许的回调 URL | PACKAGE_ID://YOUR_DOMAIN/capacitor/PACKAGE_ID/callback |
| 允许的登出 URL | PACKAGE_ID://YOUR_DOMAIN/capacitor/PACKAGE_ID/callback |
| 允许的来源 | capacitor://localhost, http://localhost |
将 PACKAGE_ID 替换为 capacitor.config.ts 中的 appId(例如 com.example.myapp),并将 YOUR_DOMAIN 替换为你的 Auth0 域名。
注意: 使用自动设置时,Auth0 CLI 会自动配置这些 URL。使用手动设置时,用户必须在 Auth0 Dashboard 中配置这些 URL。
注意: 对于本地 Web 开发(
ionic serve),还需将http://localhost:8100添加到允许的回调 URL、允许的登出 URL 和允许的 Web 来源中。
第 3 步:配置 SDK
在 src/app/app.module.ts(NgModule)或 src/app/app.config.ts(独立模式)中:
provideAuth0() 函数(或 AuthModule.forRoot())相当于 Angular 中的 Auth0Provider——它充当提供程序/包装器,用于包装应用并让 AuthService 在所有位置都可用。使用 ionic serve 进行本地 Web 开发时,回调 URL 为 http://localhost:8100。
独立模式(Angular 17+):
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 及更早版本):
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 {}
第 4 步:处理深层链接回调(AppComponent)
在应用根组件中注册 appUrlOpen 监听器,使其在导航过程中持续有效:
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();
}
});
});
}
}
第 5 步:实现登录
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();
}
}
第 6 步:实现登出
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();
}
}
第 7 步:显示用户资料
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) {}
}
第 8 步:构建和测试
Agent 指令: 编写完所有代码后,验证构建是否成功:
npm run build npx cap sync如果构建失败,请调查错误并修复(最多尝试 5-6 次)。如果仍然失败,请使用
AskUserQuestion向用户寻求帮助。
详细文档
- 设置指南 — Auth0 配置、Auth0 CLI 设置、Capacitor 平台设置、深层链接
- 集成模式 — 登录/登出流程、令牌管理、用户资料、错误处理、Capacitor 生命周期
- API 参考与测试 — AuthService API、配置选项、声明参考、测试清单
常见错误
| 错误 | 修复方法 |
|---|---|
| Auth0 应用类型设为 SPA,而不是 Native | 在 Auth0 Dashboard → Application Settings 中改为 Native |
| Auth0 Dashboard 中缺少回调 URL | 将 PACKAGE_ID://{domain}/capacitor/PACKAGE_ID/callback 添加到 Allowed Callback URLs 和 Allowed Logout URLs |
未将 handleRedirectCallback 包装在 ngZone.run() 中 | Angular 将无法检测到身份验证状态变化——始终使用 ngZone.run() 包装 |
使用 window.location.href 进行登录重定向 | 必须使用 @capacitor/browser 中的 Browser.open() 打开系统浏览器 |
未将 useRefreshTokens 设为 true | 移动端必需——localStorage 在原生平台上不可靠 |
未将 useRefreshTokensFallback 设为 false | 必须设为 false,以避免回退到基于 iframe 的令牌刷新方式(移动端不支持) |
缺少用于处理深层链接的 @capacitor/app 监听器 | 必须使用 appUrlOpen 监听器处理系统浏览器返回的回调 |
在移动端使用 loginWithPopup | 弹窗在原生平台上无法使用——请使用 loginWithRedirect 和 Browser.open |
| 回调 URL 不匹配(scheme 与 package ID 不一致) | URL scheme 必须与 capacitor.config.ts 中的 appId 完全一致 |
WebAuth 方法
Ionic 与 Capacitor 使用 Web Auth 方法进行身份验证:
- 用户点击 Log In → 应用调用
loginWithRedirect,并使用自定义的openUrl调用Browser.open() - Capacitor 的 Browser 插件在系统浏览器中打开 Auth0 Universal Login 页面(SFSafariViewController / Chrome Custom Tabs)
- 用户完成身份验证 → Auth0 重定向到自定义 URL scheme 回调
- 操作系统将深层链接路由到应用 → 触发
appUrlOpen事件 handleRedirectCallback(url)在ngZone.run()中处理身份验证码交换Browser.close()关闭系统浏览器auth.isAuthenticated$发出true,auth.user$发出用户资料
相关技能
- auth0-ionic-react — 使用 Capacitor 的 Ionic React
- auth0-ionic-vue — 使用 Capacitor 的 Ionic Vue
- auth0-angular — Angular SPA(仅限浏览器)
- auth0-swift — 原生 iOS(Swift)
- auth0-android — 原生 Android(Kotlin)
快速参考
| API | 描述 |
|---|---|
AuthService.loginWithRedirect(options) | 使用自定义的 openUrl 为 Capacitor 启动登录流程 |
AuthService.logout(options) | 使用自定义的 openUrl 和 returnTo 登出 |
AuthService.handleRedirectCallback(url) | 处理来自深层链接的回调 URL |
AuthService.isAuthenticated$ | Observable 布尔值 — 用户是否已登录 |
AuthService.user$ | Observable — 当前用户资料(姓名、电子邮件、照片) |
AuthService.isLoading$ | Observable 布尔值 — SDK 初始化状态 |
AuthService.error$ | Observable — 身份验证错误 |
AuthService.getAccessTokenSilently() | 获取访问令牌(在移动设备上使用刷新令牌) |
Browser.open({ url }) | 在系统浏览器中打开 URL(Capacitor) |
CapApp.addListener('appUrlOpen', cb) | 监听深层链接回调(Capacitor) |