跳到正文

sdk/ios

适用于 iOS 和 macOS 的 Swift SDK,使用 ASWebAuthenticationSession、PKCE S256 授权码流程和 Keychain token 存储。

状态

包状态为 已实现 · 本地已验证。单元测试(19 个通过)在 macOS 上针对 iOS 模拟器运行。针对运行中 XID 实例的 IdP 往返验证待人工核实。本页面记录已实现的行为,不代表生产就绪声明。

要求

  • iOS 16+ / macOS 13+
  • Swift 5.9+ 和 Xcode 15+
  • 无第三方依赖——仅使用 Apple 系统框架

安装

通过 Xcode 中的 Swift Package Manager(File -> Add Package Dependencies)或直接在 Package.swift 中添加包:

// Package.swift
dependencies: [
    .package(url: "https://github.com/StringKe/xid", from: "0.1.0"),
],
targets: [
    .target(name: "YourApp", dependencies: [.product(name: "Xid", package: "xid")]),
]

快速开始

import Xid

// 1. Configure in @main App.init
Xid.shared.configure(options: XidConfiguration(
    issuer: URL(string: "https://xid.dev")!,
    clientId: "your_client_id",
    redirectUri: URL(string: "com.example.app://auth/callback")!,
    scopes: ["openid", "profile", "email", "offline_access"]
))

// 2. Sign in (opens ASWebAuthenticationSession)
try await Xid.shared.signIn()

// 3. Handle redirect in SceneDelegate
let session = try await Xid.shared.handleRedirect(url: callbackUrl)

// 4. Get current session (auto-refreshes near expiry)
if let session = try await Xid.shared.getSession() {
    let token = try await Xid.shared.getAccessToken()
}

// 5. Sign out
try await Xid.shared.signOut(callEndSession: true)

核心 API

方式 描述
configure(options:) 使用 issuer、clientId、redirectUri、scopes 初始化。在其他方法之前调用。
signIn(options:) async throws 以 PKCE S256 授权 URL 打开 ASWebAuthenticationSession。浏览器会话结束时返回。
handleRedirect(url:) async throws -> XidSession 校验 OAuth state,在 token 端点交换授权码,将 token 持久化到 Keychain,并返回会话。
getSession() async throws -> XidSession? 返回存储的会话,接近过期时触发 refresh token 轮换。
getAccessToken(forceRefresh:) async throws -> String 返回有效的访问令牌字符串,如需刷新则自动刷新。
signOut(callEndSession:) async throws 清除 Keychain token。传入 true 可通过浏览器调用 end_session 端点。
setTokenStorage(_:) throws 用自定义 TokenStorageAdapter 实现替换默认的 KeychainTokenStorage。

存储适配器

默认存储使用带 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 的 Keychain——token 不会同步到 iCloud Keychain。实现 TokenStorageAdapter 协议以使用企业 Keychain 策略:

struct EnterpriseKeychain: TokenStorageAdapter {
    func save(key: String, value: String) throws { /* ... */ }
    func load(key: String) throws -> String? { /* ... */ }
    func delete(key: String) throws { /* ... */ }
}
try Xid.shared.setTokenStorage(EnterpriseKeychain())

安全

  • 公共客户端——不存储或传输客户端密钥。
  • 仅 PKCE S256。服务器拒绝 plain challenge 方式。
  • 每次请求生成随机 OAuth state;在重定向时验证以防 CSRF。
  • PKCE code_verifier 仅在授权流程期间写入 Keychain,code 交换完成后立即删除。
  • 以 prefersEphemeralWebBrowserSession = true 启动 ASWebAuthenticationSession,避免跨应用共享浏览器 cookie。

已知限制

  • 基于 JWKS 的 ES256/RS256 ID token 验签、end_session 登出和 refresh single-flight 已实现并完成本地测试。真实 iOS 设备或模拟器上的 IdP 往返验证前仍不具备 L4 支持。
  • 必须在 Xcode 设备或模拟器测试中验证 Keychain 行为。
导航

输入内容以搜索...

使用方向键导航按 Enter 键选择按 Escape 键关闭