コンテンツへ移動

sdk/ios

ASWebAuthenticationSession、PKCE S256 認可コードフロー、Keychain トークンストレージを使用した iOS および macOS 向け Swift SDK。

Markdown で表示

状態

パッケージのステータスは 実装済み・ローカル検証済み です。iOS package の Swift 単体テストスイートは macOS 上で成功しています。simulator または実機での動作と、稼働中の XID instance に対する実際の IdP ラウンドトリップは、引き続き手動検証待ちです。このページは実装済みの動作を説明するものであり、本番対応済みであるとの主張ではありません。

Registry 状態: UNPUBLISHED。この SDK はリポジトリのソース checkout からのみインストールし、外部 package registry は使用しないでください。

動作要件

  • iOS 16+ / macOS 13+
  • Swift 5.9+ および Xcode 15+
  • サードパーティ依存関係なし — Apple システムフレームワークのみ使用

インストール

Xcode(File -> Add Package Dependencies)または直接 Package.swift で Swift Package Manager を使ってパッケージを追加します:

// Package.swift
dependencies: [
    .package(path: "../xid/sdk/ios"),
],
targets: [
    .target(name: "YourApp", dependencies: [.product(name: "Xid", package: "ios")]),
]

クイックスタート

import Xid

// 1. Configure in @main App.init. offline_access is rejected until DPoP is implemented.
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"]
))

// 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. Read the current unexpired session. Expiry requires reauthorization.
if let session = try await Xid.shared.getSession() {
    let token = try await Xid.shared.getAccessToken()
}

// 5. Clear local state and optionally call end_session.
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 を検証し、トークンエンドポイントで認可コードを交換し、トークンを Keychain に永続化してセッションを返します。
getSession() async throws -> XidSession? 現在の有効期限内の iOS セッションを返します。token state の有効期限が切れている場合は消去し、メソッドは nil を返します。
getAccessToken(forceRefresh:) async throws -> String 現在の有効期限内の access token を返します。DPoP が実装されるまで SDK は offline_access を拒否します。有効期限が切れた場合は再認可が必要です。
signOut(callEndSession:) async throws Keychain トークンをクリアします。true を渡すとブラウザ経由で end_session エンドポイントを呼び出します。
setTokenStorage(_:) throws デフォルト KeychainTokenStorage をカスタム TokenStorageAdapter 実装で置き換えます。

ストレージアダプター

デフォルトストレージは kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly で Keychain を使用します。トークンは iCloud Keychain に同期されません。エンタープライズ Keychain ポリシーを使用するには TokenStorageAdapter プロトコルを実装してください:

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 チャレンジメソッドを拒否します。
  • リクエストごとに生成されるランダムな OAuth state。CSRF を防ぐためリダイレクト時に検証されます。
  • PKCE code_verifier は認可フローの間だけ Keychain に書き込まれ、コード交換直後に削除されます。
  • アプリ間でブラウザ Cookie を共有しないよう prefersEphemeralWebBrowserSession = true で起動した ASWebAuthenticationSession。

既知の制限事項

  • JWKS-backed ES256/RS256 ID token verification、nonce validation、end_session logout は実装され、ローカルでテスト済みです。L4 support の前に、iOS 実機または simulator での実 IdP round-trip が引き続き必要です。
  • Keychain の動作は Xcode の実機または simulator test で検証する必要があります。
ナビゲーション

入力して検索...

矢印キーで移動Enter キーで選択Escape キーで閉じる