状態
パッケージステータス:実装済み・ローカル検証済み。単体テスト(19 ケースパス)は iOS シミュレーターをターゲットとした macOS で実行されます。稼働中の XID インスタンスでの実際の IdP ラウンドトリップは手動検証待ちです。このページは実装済みの動作を記録したものであり、本番対応の主張ではありません。
動作要件
- iOS 16+ / macOS 13+
- Swift 5.9+ および Xcode 15+
- サードパーティ依存関係なし — Apple システムフレームワークのみ使用
インストール
Xcode(File -> Add Package Dependencies)または直接 Package.swift で Swift Package Manager を使ってパッケージを追加します:
// 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 を検証し、トークンエンドポイントで認可コードを交換し、トークンを Keychain に永続化してセッションを返します。 |
getSession() async throws -> XidSession? |
保存されたセッションを返します。期限切れ間近の場合はリフレッシュトークンのローテーションをトリガーします。 |
getAccessToken(forceRefresh:) async throws -> String |
有効なアクセストークン文字列を返します。必要な場合は自動更新します。 |
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 による ES256/RS256 ID token 検証、end_session logout、refresh single-flight は実装済みでローカルテスト済みです。L4 には iOS 実機または simulator の IdP 検証が必要です。
- Keychain の動作は Xcode の実機または simulator test で検証する必要があります。