Swift(iOS/macOS)中的授权与认证
授权与认证是任何现代应用程序的关键组成部分。在 Apple 生态系统(iOS/macOS)中,开发者可以使用强大的框架和库来简化这些流程。在本文中,我们将介绍主要方法、流行的库,并提供 Swift 的实用示例。
基本概念
在进入代码之前,区分两个术语很重要:
- 认证 — 验证用户身份(例如,用户名+密码、Face ID、Touch ID)。
- 授权 — 认证后确定访问权限(例如,用户是否可以查看特定数据)。
Apple 内置功能
1. LocalAuthentication(Face ID / Touch ID)
LocalAuthentication 框架允许使用设备的生物识别数据进行认证。
import LocalAuthentication
func authenticateWithBiometrics() { let context = LAContext() var error: NSError? // 检查生物识别是否可用 guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else { print("生物识别不可用:\\(error?.localizedDescription ?? "错误")") return } // 请求认证 context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "登录以访问应用程序") { success, authError in DispatchQueue.main.async { if success { print("认证成功") } else { print("错误:\\(authError?.localizedDescription ?? "未知错误")") } } }}2. Keychain Services
Keychain 是用于密码和令牌的安全存储。在认证后使用它来存储凭据。
import Security
func saveToKeychain(service: String, account: String, password: String) { guard let passwordData = password.data(using: .utf8) else { return } let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecValueData as String: passwordData ] // 如果存在旧数据,则删除 SecItemDelete(query as CFDictionary) // 添加新数据 let status = SecItemAdd(query as CFDictionary, nil) if status == errSecSuccess { print("数据已保存到 Keychain") } else { print("保存错误:\\(status)") }}
func readFromKeychain(service: String, account: String) -> String? { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecReturnData as String: true, kSecMatchLimit as String: kSecMatchLimitOne ] var item: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &item) guard status == errSecSuccess, let data = item as? Data else { return nil } return String(data: data, encoding: .utf8)}流行的授权库
1. Firebase Authentication
Firebase 提供了通过电子邮件/密码、Google、Apple、Facebook 和其他提供商进行认证的现成解决方案。
import FirebaseAuth
func signInWithEmail(email: String, password: String) { Auth.auth().signIn(withEmail: email, password: password) { result, error in if let error = error { print("登录错误:\\(error.localizedDescription)") return } print("用户已登录:\\(result?.user.uid ?? "无")") }