Statut
Le statut du package est Implémenté · vérifié localement. Les testsunitaires (19 réussis) s’exécutent sur macOS ciblant un simulateur iOS.L’aller-retour réel avec un IdP sur une instance XID active est en attentede vérification manuelle. Cette page documente le comportement implémenté; ce n’est pas une affirmation de disponibilité en production.
Prérequis
- iOS 16+ / macOS 13+
- Swift 5.9+ et Xcode 15+
- Aucune dépendance tierce — utilise uniquement les frameworks système Apple
Installation
Ajoutez le package via Swift Package Manager dans Xcode (Fichier ->Ajouter des dépendances de package) ou directement dansPackage.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")]),
]Démarrage rapide
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 principale
| Méthode | Description |
|---|---|
configure(options:) |
Initialiser avec issuer, clientId, redirectUri, scopes. À appeler avanttout autre. |
signIn(options:) async throws |
Ouvrir ASWebAuthenticationSession avec l’URL d’autorisation PKCE S256.Retourne lorsque la session du navigateur se termine. |
handleRedirect(url:) async throws -> XidSession |
Valider l’état OAuth, échanger le code d’autorisation au point determinaison de jeton, persister les jetons dans le Keychain et retournerune session. |
getSession() async throws -> XidSession? |
Retourner la session stockée, en déclenchant une rotation du jetond’actualisation si proche de l’expiration. |
getAccessToken(forceRefresh:) async throws -> String |
Retourner une chaîne de jeton d’accès valide, en rafraîchissantautomatiquement si nécessaire. |
signOut(callEndSession:) async throws |
Effacer les jetons Keychain. Passez true pour appeler le point determinaison end_session via le navigateur. |
setTokenStorage(_:) throws |
Remplacer le KeychainTokenStorage par défaut par une implémentationpersonnalisée de TokenStorageAdapter. |
Adaptateur de stockage
Le stockage par défaut utilise le Keychain aveckSecAttrAccessibleAfterFirstUnlockThisDeviceOnly — les jetons nesont pas synchronisés sur le Keychain iCloud. Implémentez le protocoleTokenStorageAdapter pour utiliser une politique Keychaind’entreprise :
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())Sécurité
- Client public — aucun secret client stocké ni transmis.
- PKCE S256 uniquement. Le serveur rejette la méthode plain challenge.
- État OAuth aléatoire généré par requête ; validé lors de la redirectionpour prévenir le CSRF.
- Le code_verifier PKCE est écrit dans le Keychain uniquement pendant leflux d’autorisation et supprimé immédiatement après l’échange de code.
- ASWebAuthenticationSession lancée avec prefersEphemeralWebBrowserSession =true pour éviter de partager les cookies du navigateur entre applications.
Limites connues
- La verification ES256/RS256 du jeton ID par JWKS, la deconnexion end_session et refresh single-flight sont implementes et testes localement. Un test IdP reel sur appareil ou simulateur iOS reste requis avant L4.
- Le comportement Keychain doit etre verifie avec un test Xcode sur appareil ou simulateur.