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.
In today’s digital landscape, security and user experience are paramount. Biometric authentication offers:
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:
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
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.