Implementing Biometric Login in React Native: A Comprehensive Guide for iOS
Biometric authentication has become an essential feature for mobile applications, providing users with a convenient and secure way to access their accounts. With biometrics, users can authenticate using Face ID, Touch ID, or fallback to device passcodes. This guide explains how to implement biometric login in a React Native application by bridging native iOS code with your React Native app.
Why Biometric Authentication?
In today’s digital landscape, security and user experience are paramount. Biometric authentication offers:
- Quick and seamless login experience.
- Enhanced security compared to traditional password methods.
- Support for multiple authentication types (Face ID, Touch ID, device credentials).
What You’ll Learn
- How to check biometric authentication availability on iOS devices.
- How to implement biometric authentication with a fallback to device credentials.
- How to bridge native iOS code with React Native.
- How to use the functionality in your React Native app.
Step 1: Permissions Required for Biometric Authentication:
- iOS requires permission and configuration in your app to access biometric features. Update your app’s Info.plist file to include the following keys:
- <key>NSFaceIDUsageDescription</key>
- <string>We use Face ID to authenticate you securely.</string>
- <key>NSBiometricUsageDescription</key>
- <string>We use biometric authentication to enhance your security.</string>
- These keys ensure that your app requests permission from the user to use Face ID or Touch ID.
Step 2: Checking Biometric Authentication Availability:
We need to verify whether biometric authentication is supported on the device. This is done using the LAContext class from Apple’s LocalAuthentication framework.
Native Code (iOS)
Create a method in your native module to check biometric authentication availability:
import LocalAuthentication
import React
@objc(NativeBridge)
class NativeBridge: NSObject {
@objc
func checkBiometricAuthAvailable(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let context = LAContext()
var error: NSError?
let isAvailable = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
if isAvailable {
resolve(true)
} else {
resolve(false)
}
}
}
This method checks if biometric authentication (Face ID or Touch ID) is available on the device and returns a boolean value.
Step 3: Implementing Biometric Authentication:
Now, let’s create a method to authenticate users using biometrics. If biometrics aren’t available, we’ll fallback to device passcodes.
@objc
func authenticateWithBiometric(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let context = LAContext()
let reason = “Authenticate to access your account.”
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { success, error in
if success {
resolve(“AUTH_SUCCESS”)
} else if let error = error as NSError? {
let errorCode = error.code
switch errorCode {
case LAError.authenticationFailed.rawValue:
reject(“AUTH_FAILED”, “Authentication failed.”, nil)
case LAError.userCancel.rawValue:
reject(“USER_CANCELLED”, “Authentication was cancelled by the user.”, nil)
case LAError.userFallback.rawValue:
reject(“USER_FALLBACK”, “User chose to use fallback authentication method.”, nil)
case LAError.biometryNotAvailable.rawValue:
reject(“BIOMETRY_NOT_AVAILABLE”, “Biometric authentication is not available.”, nil)
case LAError.biometryNotEnrolled.rawValue:
reject(“BIOMETRY_NOT_ENROLLED”, “Biometric authentication is not enrolled.”, nil)
default:
reject(“AUTH_ERROR”, “An unknown error occurred.”, nil)
}
}
}
}
This method:
- Displays the biometric authentication prompt.
- Authenticates the user with Face ID, Touch ID, or device passcode.
- Handles success, errors, and user cancellation.
Step 4: Bridging Native Code with React Native :
To make these methods accessible in React Native, create a bridging module.
NativeBridge.m
#import “React/RCTBridgeModule.h”
@interface RCT_EXTERN_MODULE(NativeBridge, NSObject)
RCT_EXTERN_METHOD(checkBiometricAuthAvailable: (RCTPromiseResolveBlock)resolve reject: (RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(authenticateWithBiometric: (RCTPromiseResolveBlock)resolve reject: (RCTPromiseRejectBlock)reject)
@end
Step 5: Register the Native Module:
Ensure the module is registered in your iOS app.
AppDelegate.swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
…
// Ensure React Native bridge is initialized properly
}
Step 6: React Native Integration:
In your React Native app, create utility functions to call the native methods.
import { NativeModules } from ‘react-native’;
export const checkBiometricAuthAvailability = async () => {
try {
const isAvailable = await NativeModules.NativeBridge.checkBiometricAuthAvailable();
return isAvailable;
} catch (error) {
return false;
}
};
export const authenticateWithBiometric = async () => {
try {
const result = await NativeModules.NativeBridge.authenticateWithBiometric();
return result === ‘AUTH_SUCCESS’;
} catch (error) {
console.log(‘Authentication Error:’, error);
return false;
}
};
Step 7: Using Biometric Authentication:
Use these functions in your React Native components to check and authenticate users.
import React, { useState } from ‘react’;
import { View, Button, Text } from ‘react-native’;
import { checkBiometricAuthAvailability, authenticateWithBiometric } from ‘./BiometricUtils’;
const App = () => {
const [authStatus, setAuthStatus] = useState(”);
const handleLogin = async () => {
const isAvailable = await checkBiometricAuthAvailability();
if (!isAvailable) {
setAuthStatus(‘Biometric authentication not available.’);
return;
}
const isAuthenticated = await authenticateWithBiometric();
setAuthStatus(isAuthenticated ? ‘Authenticated!’ : ‘Authentication Failed.’);
};
return (
<View>
<Button title=”Login with Biometrics” onPress={handleLogin} />
<Text>{authStatus}</Text>
</View>
);
};
export default App;
Next Steps
- Implement credential storage using Keychain for enhanced security.
- Add comprehensive error handling and user feedback.
- Expand the feature to support additional scenarios (e.g., two-factor authentication).
Conclusion
With this guide, you’ve added biometric authentication to your React Native app on iOS, offering users a secure and seamless login experience. Follow similar steps for Android to ensure feature parity across platforms.