Authorization and Authentication in Swift (iOS/macOS)
Authorization and authentication are key components of any modern application. In the Apple ecosystem (iOS/macOS), developers have access to powerful frameworks and libraries that simplify these processes. In this article, we will cover the main approaches, popular libraries, and provide practical examples in Swift.
Basic Concepts
Before moving to code, it is important to distinguish between two terms:
- Authentication — verifying a user's identity (e.g., login + password, Face ID, Touch ID).
- Authorization — determining access rights after authentication (e.g., whether a user can view certain data).
Built-in Apple Capabilities
1. LocalAuthentication (Face ID / Touch ID)
The LocalAuthentication framework allows using the device's biometric data for authentication.
import LocalAuthentication
func authenticateWithBiometrics() { let context = LAContext() var error: NSError? // Check if biometrics is available guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else { print("Biometrics unavailable: \\(error?.localizedDescription ?? "error")") return } // Request authentication context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Log in to access the app") { success, authError in DispatchQueue.main.async { if success { print("Authentication successful") } else { print("Error: \\(authError?.localizedDescription ?? "unknown error")") } } }}2. Keychain Services
Keychain is a secure storage for passwords and tokens. Use it to store credentials after authentication.
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 ] // Delete old data if any SecItemDelete(query as CFDictionary) // Add new data let status = SecItemAdd(query as CFDictionary, nil) if status == errSecSuccess { print("Data saved to Keychain") } else { print("Save error: \\(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)}Popular Libraries for Authorization
1. Firebase Authentication
Firebase provides a ready-made solution for authentication via email/password, Google, Apple, Facebook, and other providers.
import FirebaseAuth
func signInWithEmail(email: String, password: String) { Auth.auth().signIn(withEmail: email, password: password) { result, error in if let error = error { print("Login error: \\(error.localizedDescription)") return } print("User logged in: \\(result?.user.uid ?? "none")") } Also in library
Task Queues in Node.js: Bull, Bee-Queue and Kue
Data Validation in Kotlin: Libraries, Approaches, and Code Examples
Markdown Processing in C# (.NET): Libraries and Tools
Reactive Programming in Rust: Libraries, Frameworks, and Practical Examples