mcpField
A
auth0-swift

auth0-swift

github.com/auth0安全55477 次安装1 天前更新
代码仓库

关于 auth0-swift

面向 Apple 平台 Swift 应用的 Auth0 原生认证集成技能,使用 Auth0.swift 实现浏览器认证和 Keychain 凭据管理。覆盖 SwiftUI、UIKit、生物识别保护及多种回调 URL 配置。

主要功能

  1. 01配置 Auth0.swift SDK
  2. 02通过系统浏览器认证
  3. 03使用 Keychain 管理凭据
  4. 04添加生物识别保护
  5. 05配置回调 URL 与通用链接

适用场景

  1. 01为 Swift 应用添加 Auth0 登录
  2. 02安全保存并续期凭据
  3. 03使用生物识别保护凭据
  4. 04配置 Universal Links 登录回调

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/auth0/agent-skills --skill auth0-swift

安装后在 Claude Code 中输入/auth0-swift确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api.md
integration.md
setup.md
tests/
benchmark-config.json
evals.json
graders.json
graders.ts
package.json

详细介绍

Auth0 Swift 集成

Auth0.swift 是适用于 Apple 平台(iOS、macOS、tvOS、watchOS、visionOS)的官方 Auth0 SDK。此技能可为 Swift 应用添加完整的原生身份验证,包括使用 Web Auth(通过系统浏览器重定向)、通过 CredentialsManager 安全地将凭据存储到 Keychain,以及可选的生物识别保护。

不适用场景

前提条件

  • 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 from 2.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 指令:

  1. 读取 Auth0.plist 以获取 ClientId 和 Domain。
  2. 从 project.pbxproj 中提取 Bundle 标识符:搜索 PRODUCT_BUNDLE_IDENTIFIER,跳过包含 $( 或 Tests 的值。
  3. 通过 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>&1

Auth0 现在会自动托管 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 资源

参考资料

评论

支持 Markdown