Biometric Authentication
Bridges for device biometric authentication (fingerprint / Face ID / Touch ID), secure token storage, and decryption.
Android
Bridge object: AndroidBiometric
All async methods accept a callbackName (a global JS function name or dot-notation path) and a nonce (unique string per call). The result is delivered by calling window[callbackName](result), where result is already a parsed object - no JSON.parse required.
Callback Shape
{
success: boolean;
error?: string;
errorCode?: number;
}
Methods
Method | Description |
|---|
isAvailable()
| Returns a JSON string of { available: boolean, enrolled: boolean, type: string } |
authenticate(callbackName, nonce)
| Triggers biometric prompt, returns auth result |
authenticate(callbackName, nonce, options)
| Same, with custom UI text options |
encryptWithBiometric(callbackName, nonce, data, keyAlias)
| Biometric-gated encrypt |
encryptWithBiometric(callbackName, nonce, data, keyAlias, options)
| With custom UI text |
decryptWithBiometric(callbackName, nonce, encryptedData, keyAlias)
| Biometric-gated decrypt |
decryptWithBiometric(callbackName, nonce, encryptedData, keyAlias, options)
| With custom UI text |
deleteKey(keyAlias)
| Deletes the stored key for the given alias |
Options Object
{
"title": "string",
"subtitle": "string",
"description": "string",
"negativeButton": "string"
}
Callback Result Shapes
authenticate result:
{ success: true, errorCode: 0 }
{ success: false, error: "User cancelled", errorCode: 10 }
encryptWithBiometric result:
{ success: true, encrypted: "<base64>" }
{ success: false, error: "...", errorCode: ... }
decryptWithBiometric result:
{ success: true, decrypted: "<original data>" }
{ success: false, error: "...", errorCode: ... }
Example
// Check availability
const { available, enrolled, type } = JSON.parse(AndroidBiometric.isAvailable());
console.log('Available:', available, '| Enrolled:', enrolled, '| Type:', type);
// Authenticate
window.myAuthCallback = function(result) {
if (result.success) {
console.log('Authenticated!');
} else {
console.error('Failed:', result.error, '(code', result.errorCode + ')');
}
};
AndroidBiometric.authenticate('myAuthCallback', 'nonce-001', JSON.stringify({
title: 'Confirm identity',
negativeButton: 'Use PIN instead'
}));
// Encrypt data
window.myEncryptCallback = function(result) {
if (result.success) {
localStorage.setItem('enc', result.encrypted);
}
};
AndroidBiometric.encryptWithBiometric(
'myEncryptCallback',
'nonce-002',
'my-secret-token',
'com.myapp.authkey'
);
iOS
Bridge object: AppleBiometric (injected shim, Promise-based)
Methods
Method | Return | Description |
|---|
AppleBiometric.isAvailable()
| boolean
| Returns true if Face ID / Touch ID is available |
AppleBiometric.getBiometricType()
| string
| Returns "faceID", "touchID", or "none" |
AppleBiometric.authenticate(reason)
| Promise<void>
| Prompts biometric authentication |
AppleBiometric.saveToken(token, expiresInSeconds)
| Promise<void>
| Biometric-protected token storage in Keychain |
AppleBiometric.retrieveToken()
| Promise<string>
| Retrieves Keychain token after biometric verification |
AppleBiometric.logout()
| void
| Clears the stored token from Keychain |
Result event (for all actions): mobiweb:biometricResult
event.detail = {
action: "authenticate" | "saveToken" | "retrieveToken",
success: boolean,
token?: string, // only for retrieveToken
error?: string
}
Example
// Check availability
if (AppleBiometric.isAvailable()) {
console.log('Type:', AppleBiometric.getBiometricType()); // "faceID" or "touchID"
}
// Authenticate
AppleBiometric.authenticate('Confirm your identity')
.then(() => console.log('Authenticated!'))
.catch((err) => console.error('Auth failed:', err.message));
// Save token to Keychain
AppleBiometric.saveToken('my-auth-token', 3600)
.then(() => console.log('Token saved'))
.catch((err) => console.error(err.message));
// Retrieve token
AppleBiometric.retrieveToken()
.then((token) => console.log('Retrieved token:', token))
.catch((err) => console.error(err.message));
// Logout
AppleBiometric.logout();
async function authenticate(reason) {
if (typeof AndroidBiometric !== 'undefined') {
return new Promise((resolve, reject) => {
const nonce = 'auth-' + Date.now();
window.__bioCb = function(result) {
result.success ? resolve() : reject(new Error(result.error));
};
AndroidBiometric.authenticate('__bioCb', nonce);
});
} else if (typeof AppleBiometric !== 'undefined') {
return AppleBiometric.authenticate(reason);
}
throw new Error('Biometric not available on this platform');
}
03 May 2026