关于 auth0-swift
面向 Apple 平台 Swift 应用的 Auth0 原生认证集成技能,使用 Auth0.swift 实现浏览器认证和 Keychain 凭据管理。覆盖 SwiftUI、UIKit、生物识别保护及多种回调 URL 配置。
主要功能
- 01配置 Auth0.swift SDK
- 02通过系统浏览器认证
- 03使用 Keychain 管理凭据
- 04添加生物识别保护
- 05配置回调 URL 与通用链接
适用场景
- 01为 Swift 应用添加 Auth0 登录
- 02安全保存并续期凭据
- 03使用生物识别保护凭据
- 04配置 Universal Links 登录回调
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ auth0/ agent-skills --skill auth0-swift安装后在 Claude Code 中输入/auth0-swift确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api.mdintegration.mdsetup.mdtests/benchmark-config.jsonevals.jsongraders.jsongraders.tspackage.json详细介绍
Auth0 Swift 集成
Auth0.swift 是适用于 Apple 平台(iOS、macOS、tvOS、watchOS、visionOS)的官方 Auth0 SDK。此技能可为 Swift 应用添加完整的原生身份验证,包括使用 Web Auth(通过系统浏览器重定向)、通过 CredentialsManager 安全地将凭据存储到 Keychain,以及可选的生物识别保护。
不适用场景
- Android 应用:使用 auth0-android
- React Native 应用:使用 auth0-react-native
- Flutter 应用:使用原生 Flutter Auth0 SDK
- Web SPA(React、Angular、Vue):使用 auth0-react、auth0-angular 或 auth0-vue
- Node.js/Express 服务端:使用 auth0-express
前提条件
- iOS 14.0+ / macOS 11.0+ / tvOS 14.0+ / watchOS 7.0+ / visionOS 1.0+
- Xcode 16.x
- Swift 6.0+
- Auth0 账户 — 免费注册
- Auth0 CLI —
brew install auth0/auth0-cli/auth0(用于自动化设置)
快速入门工作流
**Agent 指令:**按顺序执行以下步骤。如果任何步骤遇到错误,先尝试修复,最多重试 5 次,然后再调用
AskUserQuestion向用户寻求指导。始终先搜索现有代码——如果已有登录/登出处理程序,应接入这些处理程序,而不是新建。**重要——凭据隐私:**切勿在回复文本或终端输出中显示 Auth0 凭据(域名、客户端 ID、客户端密钥)。使用 Write 或 Edit 工具直接将它们写入配置文件。运行会在输出中包含这些值的 Auth0 CLI 命令时,请将输出重定向到文件,并以编程方式读取。例如:
auth0 apps create ... --json --no-input > /tmp/auth0-output.json 2>&1然后使用 Read 工具读取
/tmp/auth0-output.json,提取所需值并将其直接写入Auth0.plist或其他配置文件——切勿在回复文本或终端中显示这些值。向用户确认当前租户时,请使用遮蔽格式(例如your-te****.us.auth0.com)。
步骤 1 — 安装 SDK
**Agent 指令:**检查项目目录中是否存在以下包管理器文件:
- 存在
Podfile→ CocoaPods- 存在
Cartfile→ Carthage- 存在
Package.swift→ Swift Package Manager如果都没有找到,请通过
AskUserQuestion询问:“你的项目使用哪种依赖管理器——Swift Package Manager、CocoaPods 还是 Carthage?”**Swift Package Manager —
Package.swift项目:**在项目根目录运行以下命令以自动添加依赖,然后在Package.swift中将"Auth0"添加到目标的dependencies数组:swift package add-dependency https://github.com/auth0/Auth0.swift --from 2.18.0**Swift Package Manager — Xcode 项目(
.xcodeproj,没有Package.swift):**不适用 CLI 命令。请指导用户通过 Xcode 添加包:File → Add Package Dependencies →https://github.com/auth0/Auth0.swift→ Up to Next Major Version from2.18.0。**CocoaPods 或 Carthage:**按照设置指南中对应的安装步骤操作。不要只展示说明——请实际编辑文件并运行命令。
步骤 2 — 配置 Auth0
Agent 指令:
- 如果用户的提示词中已经包含 Auth0 凭据(域名和客户端 ID): 直接使用这些值写入
Auth0.plist— 不要向用户提问,不要在 Swift 源文件中硬编码这些值,也不要将它们作为参数传递给Auth0.webAuth()或Auth0.authentication()。SDK 会自动读取Auth0.plist— 始终使用不带参数的形式Auth0.webAuth()。然后继续执行步骤 3。- 如果项目中已存在
Auth0.plist文件: 读取该文件以提取ClientId和Domain,然后继续执行步骤 3。- 如果不存在
Auth0.plist,且用户未提供凭据: 通过AskUserQuestion询问用户:"你希望如何配置 Auth0?"
- 自动(Auth0 CLI) — 我将创建应用程序、设置回调 URL,并使用 Auth0 CLI 完成所有配置。
- 手动 — 你提供预先配置好的
Auth0.plist文件,我会将其添加到项目中。如果用户选择自动:按照设置指南 — 通过 Auth0 CLI 自动设置操作。 如果用户选择手动:按照设置指南 — 手动设置操作。
Auth0.plist格式:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ClientId</key> <string>YOUR_CLIENT_ID</string> <key>Domain</key> <string>YOUR_DOMAIN</string> </dict> </plist>将
Auth0.plist放在与应用的 Swift 源文件相同的目录中,以便 SDK 自动找到它。
步骤 3 — 配置回调 URL
Agent 指令:
- 读取
Auth0.plist以获取ClientId和Domain。- 从
project.pbxproj中提取 Bundle 标识符:搜索PRODUCT_BUNDLE_IDENTIFIER,跳过包含$(或Tests的值。- 通过
AskUserQuestion询问用户:"你希望使用哪种回调 URL 方案?"
- 自定义方案(
{bundle}://)— 更简单,适用于所有 Apple 平台- HTTPS 通用链接 — 推荐用于生产环境;可防止 URL 方案劫持
然后仅按照下方匹配的路径操作。
路径 A — 自定义方案
Agent 指令: 使用 Auth0 CLI 注册回调 URL(将
CLIENT_ID、BUNDLE_ID、DOMAIN替换为实际值)。首先,获取现有的回调和注销 URL,避免覆盖它们:
auth0 apps show CLIENT_ID --json --no-input > /tmp/auth0-app-info.json 2>&1读取
/tmp/auth0-app-info.json以提取现有的callbacks和allowed_logout_urls数组。然后将任何现有 URL 与新 URL 一并列出,以逗号分隔:
auth0 apps update CLIENT_ID \ --callbacks "EXISTING_CALLBACKS,BUNDLE_ID://DOMAIN/ios/BUNDLE_ID/callback" \ --logout-urls "EXISTING_LOGOUT_URLS,BUNDLE_ID://DOMAIN/ios/BUNDLE_ID/callback" \ --no-input > /dev/null 2>&1如果没有现有 URL,则省略
EXISTING_前缀,仅使用新 URL。然后按照设置指南中的 URL 方案注册步骤,在 Xcode 中将
$(PRODUCT_BUNDLE_IDENTIFIER)注册为 URL 类型。
路径 B — HTTPS 通用链接
Agent 指令: 以下四个步骤均为必需步骤 — 跳过任何一步都会导致登录后回调重定向静默失败。
步骤 B1 — 通过 Auth0 CLI 注册回调 URL: 同时注册 HTTPS 和自定义 scheme,确保应用在所有场景下均可正常工作。
首先,获取现有的回调和登出 URL,避免覆盖它们:
auth0 apps show CLIENT_ID --json --no-input > /tmp/auth0-app-info.json 2>&1读取
/tmp/auth0-app-info.json,提取现有的callbacks和allowed_logout_urls数组。然后,将任何现有 URL 与新 URL 一起以逗号分隔的列表形式传入:
auth0 apps update CLIENT_ID \ --callbacks "EXISTING_CALLBACKS,https://DOMAIN/ios/BUNDLE_ID/callback,BUNDLE_ID://DOMAIN/ios/BUNDLE_ID/callback" \ --logout-urls "EXISTING_LOGOUT_URLS,https://DOMAIN/ios/BUNDLE_ID/callback,BUNDLE_ID://DOMAIN/ios/BUNDLE_ID/callback" \ --no-input > /dev/null 2>&1如果没有现有 URL,请省略
EXISTING_前缀,仅使用新 URL。步骤 B2 — 通过 Auth0 CLI 配置设备设置: 从
project.pbxproj中提取DEVELOPMENT_TEAM(10 个字符的值,例如ABC12DE34F)。如果未找到,请通过AskUserQuestion询问:"您的 Apple Team ID 是什么?(developer.apple.com → Account → Membership Details)"auth0 api patch applications/CLIENT_ID \ --data '{"mobile":{"ios":{"team_id":"TEAM_ID","app_bundle_identifier":"BUNDLE_ID"}}}' \ --no-input > /dev/null 2>&1Auth0 现在会自动托管
apple-app-site-association文件 — 这是设备上的通用链接正常工作所必需的。步骤 B3 — 在 Xcode 中添加 Associated Domains 权限: 将
com.apple.developer.associated-domains添加到应用的.entitlements文件中,并为 Auth0 域名添加applinks:和webcredentials:条目。完整的权限 XML、Xcode 功能配置步骤和构建设置验证,请参阅 设置指南 — Associated Domains。步骤 B4 — 在 SDK 中使用
.useHTTPS():Auth0.webAuth().useHTTPS()
步骤 4 — 实现身份验证
Agent 指令: 在项目中搜索
@main struct(SwiftUI)或AppDelegate/UIViewController(UIKit),以检测 UI 框架。如果无法确定,请通过AskUserQuestion询问:"您的应用使用 SwiftUI 还是 UIKit?" 然后仅遵循下面匹配的路径。重要 — 切勿在代码中传递凭据: 不要将
clientId或domain作为参数传递给Auth0.webAuth()、Auth0.authentication()或任何其他 SDK 调用。SDK 会自动从Auth0.plist读取这些值。始终使用无参数形式:Auth0.webAuth() // ✓ 自动读取 Auth0.plist Auth0.authentication() // ✓ 自动读取 Auth0.plist Auth0.webAuth(clientId: "...", domain: "...") // ✗ 切勿这样做 Auth0.authentication(clientId: "...", domain: "...") // ✗ 切勿这样做
SwiftUI
Agent 指令: 创建
AuthenticationService.swift并将其实现为ObservableObject,然后将其接入应用入口和根视图。搜索@main结构体和ContentView(或等效的根视图),并按以下示例进行更新。
// AuthenticationService.swift
import Auth0
import Combine
class AuthenticationService: ObservableObject {
@Published var isAuthenticated = false
private let credentialsManager = CredentialsManager(authentication: Auth0.authentication())
init() { isAuthenticated = credentialsManager.canRenew() }
func login() async {
do {
let credentials = try await Auth0
.webAuth()
.useHTTPS()
.scope("openid profile email offline_access")
.start()
_ = credentialsManager.store(credentials: credentials)
await MainActor.run { isAuthenticated = true }
} catch WebAuthError.userCancelled { }
catch { print("Login failed: \(error)") }
}
func logout() async {
do { try await Auth0.webAuth().useHTTPS().clearSession() }
catch { print("Logout failed: \(error)") }
_ = credentialsManager.clear()
await MainActor.run { isAuthenticated = false }
}
}
// @main App struct — inject AuthenticationService as environment object
@StateObject private var auth = AuthenticationService()
// In body: ContentView().environmentObject(auth)
// Root ContentView — branch on authentication state
@EnvironmentObject var auth: AuthenticationService
// In body: if auth.isAuthenticated { HomeView() } else { LoginView() }
有关完整的 SwiftUI 应用生命周期接入方式,请参阅 集成模式。
UIKit
Agent 指令: 创建普通的
AuthenticationService.swift类,然后在相关的UIViewController中添加登录/登出调用。另请检查应用是否使用SFSafariViewController——如果使用,请将WebAuthentication.resume(with:)添加到AppDelegate/SceneDelegate(参见下方说明)。
// AuthenticationService.swift
import Auth0
class AuthenticationService {
private let credentialsManager = CredentialsManager(authentication: Auth0.authentication())
var isAuthenticated: Bool { credentialsManager.canRenew() }
func login() async throws {
let credentials = try await Auth0
.webAuth()
.useHTTPS()
.scope("openid profile email offline_access")
.start()
_ = credentialsManager.store(credentials: credentials)
}
func logout() async throws {
try await Auth0.webAuth().useHTTPS().clearSession()
_ = credentialsManager.clear()
}
}
// In your UIViewController
private let auth = AuthenticationService()
@IBAction func loginTapped(_ sender: UIButton) {
Task {
do {
try await auth.login()
await MainActor.run { navigateToHome() }
} catch WebAuthError.userCancelled { }
catch { print("Login failed: \(error)") }
}
}
@IBAction func logoutTapped(_ sender: UIButton) {
Task {
do { try await auth.logout() }
catch { print("Logout failed: \(error)") }
await MainActor.run { navigateToLogin() }
}
}
注意 — 仅适用于 SFSafariViewController: 如果应用使用
.provider(WebAuthentication.safariProvider()),而非默认的ASWebAuthenticationSession,请将WebAuthentication.resume(with: url)添加到AppDelegate.application(_:open:url:options:)和SceneDelegate.scene(_:openURLContexts:)。确切代码请参见集成模式。
步骤 5 — 验证构建
Agent 指令: 运行构建,验证集成能否无错误地编译:
xcodebuild build -scheme YOUR_SCHEME -destination "platform=iOS Simulator,name=iPhone 16"如果构建失败,请检查错误消息并修复,最多尝试 5 次,然后再询问用户。
详细文档
- 设置指南 — Auth0 CLI 配置、Auth0.plist、URL 方案注册、关联域、CocoaPods/SPM/Carthage 安装
- 集成模式 — Web Auth 登录/登出、CredentialsManager、生物识别保护、MFA、组织、错误处理、SwiftUI/UIKit 模式
- API 参考与测试 — 完整 API 参考、配置选项、声明参考、测试清单、故障排查
常见错误
| 错误 | 修复方法 |
|---|---|
| Auth0 应用类型未设为 Native | 在 Auth0 Dashboard 中创建应用时,选择 “Native” |
| Auth0 Dashboard 中缺少回调 URL | 将 https:// 通用链接和 {bundle}:// 自定义方案都添加到允许的回调 URL 和登出 URL 中 |
未将 Auth0.plist 添加到 Xcode 目标 | 在导航器中右键点击文件 → “Add Files to Target” → 勾选你的应用目标 |
缺少 offline_access 范围 | 在范围字符串中添加 "offline_access",以接收用于静默续期的刷新令牌 |
将令牌存储在 UserDefaults 中 | 始终使用 CredentialsManager——它会通过访问控制将令牌存储在 Keychain 中 |
在调用 store() 前调用 credentialsManager.credentials() | 尝试获取凭据前,先存储登录结果中的凭据 |
(CocoaPods)打开了 .xcodeproj 而非 .xcworkspace | 运行 pod install 后,始终打开 .xcworkspace 文件 |
登出时未调用 clearSession() | 始终调用 clearSession(),以从浏览器中移除 Auth0 会话 Cookie |
| 构建错误 “No such module 'Auth0'” | 确认软件包已添加到正确的目标;使用 CocoaPods 时,请打开 .xcworkspace |
| 提示词中已提供域名/客户端 ID,却在 Swift 源代码中硬编码 | 将它们写入 Auth0.plist,并不带参数调用 Auth0.webAuth()——SDK 会自动读取 plist |
相关技能
auth0-quickstart- Auth0 基础设置auth0-cli- 在终端中管理 Auth0 资源