Implement Face ID Authentication in the iOS App
Enhance your iOS app's security and user experience with FaceID
Exciting News! Our blog has a new home! 🚀
Introduction
Biometric authentication has transformed mobile security, and Apple’s Face ID, introduced with the iPhone X in 2017, stands at the forefront of this revolution.
Utilizing advanced facial recognition technology, Face ID goes beyond traditional methods by leveraging depth-sensing cameras and machine learning algorithms.
Stored securely within the device’s Secure Enclave, Face ID creates a mathematical representation of facial features, ensuring unparalleled security. Moreover, its seamless integration into iOS apps has redefined user interactions, setting new standards for mobile authentication.
In this blog, we’ll delve into the process of integrating Face ID into iOS apps to enhance both security and user experience.
Understanding Face ID
Face ID replaces the conventional Touch ID with a sophisticated facial recognition system, providing users with a secure and effortless means of unlocking their devices and validating actions.
Utilizing the TrueDepth camera system, Face ID captures and analyzes facial features in real-time, generating a precise 3D map.
This map, created from thousands of infrared dots projected onto the face, forms a unique Faceprint and is securely stored within the device’s Secure Enclave.
During authentication, Face ID compares the current facial data with the stored Faceprint, utilizing machine learning to adapt to changes in appearance and ensure consistent performance.
In essence, Face ID represents a user-friendly authentication solution that integrates cutting-edge technology to redefine mobile security and user experience standards on iOS devices.
1. Face ID’s Advantages
Face ID presents a significant leap forward in security and convenience compared to traditional password or PIN-based authentication methods.
By relying on facial recognition technology, it eliminates the need for manual input, offering users a seamless and hands-free authentication experience.
Furthermore, the inherent uniqueness of facial features makes Face ID exceptionally secure, greatly reducing the risk of phishing attacks.
2. Addressing Concerns
Misconceptions surrounding Face ID’s security and privacy have led to concerns about data storage and privacy risks.
However, it’s crucial to understand that Face ID securely stores facial data locally on the device, making it inaccessible to apps or cloud services.
Additionally, it continually improves its performance through machine learning algorithms, enhancing security measures while safeguarding user privacy.
Since Face ID operates solely on the device, it doesn’t transmit facial data externally, mitigating privacy concerns and ensuring user data remains protected.
Requirements & Prerequisites
To successfully integrate Face ID into iOS apps, developers need to meet specific hardware, software, and prerequisite criteria.
1. Hardware Requirements
Ensure the device includes a TrueDepth camera system (a key component for Face ID functionality) available on iPhone X and later models.
2. Software Requirements
Face ID integration requires a minimum iOS version compatible with the TrueDepth camera, typically iOS 11 or later.
3. Prerequisites
1. Privacy Considerations: Developers should dhere to Apple's privacy guidelines and obtain user consent when accessing biometric data for authentication.
2. App Capabilities: Ensure that the app's Info.plist
file includes the necessary permissions and descriptions for accessing FaceID usage description. This is crucial for informing users about why the app requires Face ID access.
Integration Steps
To access the faceID into an iOS app involves several key steps:
Update Info.plist: Add ‘Privacy — Face ID Usage Description’ to the app’s Info.plist file. This string value informs users about the app’s use of Face ID and should be concise yet informative.Note: Keep the key as sort as possible which allow user to undestand the purpose of permission.
Create Authenticator: Create an authenticator within the app that uses Face ID APIs to authenticate users. Import the ‘LocalAuthentication’ module, which provides access to authentication-related APIs.Note: The app’s Info.plist must contain an NSFaceIDUsageDescription key with a string value explaining to the user how the app uses this data.
1. Availability Check
Here we need to check whether the device supports biometric authentication or not, to do that we have created an extension of LAContext which provides the status of availability.
extension LAContext {
enum BiometricType: String {
case none
case touchID
case faceID
case opticID // Added a case for potential future biometric methods
}
// Returns the detected biometric type based on the capabilities of the device
var biometricType: BiometricType {
var error: NSError?
// Check if the device supports biometric authentication
guard self.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
return .none
}
if #available(iOS 11.0, *) {
// Determine the specific biometric type supported on iOS 11.0 and later
switch self.biometryType {
case .none:
return .none
case .touchID:
return .touchID
case .faceID:
return .faceID
default:
if #available(iOS 17.0, *) {
// Support for potential future biometric methods
if self.biometryType == .opticID {
return .opticID
} else {
return .none
}
}
}
}
// Fallback to checking for Touch ID support on iOS versions older than 11.0
return self.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ? .touchID : .none
}
}
This extension introduces an enum BiometricType
, enabling developers to determine the supported biometric authentication method on iOS devices.
It checks for the device supports for the biometric authentication using canEvaluatePolicy(_:error:)
. If biometric authentication is not available, it returns .none
.
For devices running iOS 11.0 and later, it utilizes the biometryType
property of LAContext
to determine the supported biometric type.
Additionally, it includes a case for potential future biometric methods, such as optic scanning, and provides a fallback mechanism for devices running iOS versions older than 11.0.
2. Implementing authentication
For authentication, we have created an Authenticator class which manages all the authentication-related things.
In this class, we have the authenticate()
method to authenticate whether the user is verified or not and it will act accordingly.
private func authenticate() {
// Check if biometric authentication is available and not locked
guard isBiometricAvailable() && !isBiometricLocked else { return }
isLoading = true
var error: NSError?
// Check if biometric authentication is possible
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// Perform biometric authentication
let reason = "We need to unlock your data."
// It presents a localized reason for authentication to the user, explaining why authentication is necessary.
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { [weak self]
success, authenticationError in
guard let self else { return }
// Handle authentication completion
if success {
// proceeds to decrypt and verify the user's passcode
let passcode = self.decryptUserPasscode()
self.isAuthenticated = passcode != nil
} else {
// increments the failedAttempt count
self.failedAttempt += 1
// check for the maximum allowed failed limit
self.isBiometricLocked = self.failedAttempt >= self.maxFailedAttemptAllowed
}
self.isLoading = false
}
} else {
// Handle error if biometric authentication is not possible
if let error {
handleLaError(error: error)
} else {
// Handle other errors if any
}
}
}
This authenticate()
function is responsible for initiating the biometric authentication process.
It verifies the availability and unlock status of biometric authentication using
canEvaluatePolicy
. If it's possible, it proceeds with it and handles success or failure accordingly.If it succeeds move ahead otherwise we check for the failed limit, if it reaches the maximum limit then basically we disable the biometric authentication temporarily.
If biometric authentication is unavailable, it checks for the error. If an error is present, it handles the error appropriately.
This function provides a structured approach to biometric authentication, handling success, failure, and error scenarios gracefully while ensuring a smooth user experience.
If you ask for the
deviceOwnerAuthenticationWithBiometrics
policy then you will have to handle the fallback yourself.If you ask for
deviceOwnerAuthentication
only, then biometrics will be used if available and authorized, otherwise, it will automatically fall back to passcode if biometrics is unavailable, or give you the fallback option to enter passcode automatically if biometrics attempt fails.
3. Secure Passcode
func setPasscodeWith(_ code: String) {
// Check if biometric authentication is available
guard isBiometricAvailable() else { return }
// Generate a unique encryption key
let key = UUID().uuidString // Instead of this random string you can use a key that can be recoverable
// Encrypt the passcode using AES encryption algorithm
let encryptedPasscode = AESEncryptionManager.encrypt(plainText: code, key: key)
// Store the encrypted passcode and encryption key securely
userDefault.setValue(encryptedPasscode, forKey: userDefaultPasscodeKey)
userDefault.setValue(key, forKey: userDefaultSecretKey)
}
This Swift function setPasscodeWith(_:)
is responsible for setting a passcode using biometric authentication, if available.
Here's a breakdown of its functionality:
It checks for biometric authentication availability.
It generates a unique encryption key using
UUID().uuidString
that will be used to encrypt the passcode securely.It encrypts the provided passcode using the generated encryption key. The
AESEncryptionManager.encrypt(plainText:key:)
function encrypts the passcode using the AES encryption algorithm.It stores the encrypted passcode and the encryption key securely in the user defaults.
The encrypted passcode is stored with a key userDefaultPasscodeKey
and the encryption key is stored with a key userDefaultSecretKey
, This ensures that the passcode remains stored on the device.
If you are not aware about AES encryption then here is the good Article on it which explains AES encryption in detail.
This post only has Authentication implementation steps, to read the complete guide including Handling Fallback and Testing & Debugging implementation please visit this blog.
The post is originally published on canopas.com.
If you like what you read, be sure to hit
💖 button below! — as a writer it means the world!
I encourage you to share your thoughts in the comments section below. Your input not only enriches our content but also fuels our motivation to create more valuable and informative articles for you.
Follow Canopas to get updates on interesting articles!