Bringing Native Biometrics to Your Web App
Entering password details on a mobile screen is slow and frustrates users. Modern mobile apps solve this by offering Biometric Authentication (Face ID on iOS, and Fingerprint/Face Unlock on Android). Since standard web apps cannot access biometric hardware directly, you can use a JavaScript-to-Native bridge to authenticate users instantly.
1. The Native Biometric APIs
Android and iOS provide secure APIs to check for biometric hardware and trigger the scanner prompt:
- Android:
BiometricPrompt(part of the Jetpack Biometric library). - iOS: The
LocalAuthenticationframework (specificallyLAContext).
These APIs run securely at the OS level. The app never sees raw fingerprint or face scan data; it only receives a success or failure callback from the operating system.
2. Configuring the JavaScript Bridge
We expose a trigger method in our native code to be called from the web view.
Inside Kotlin (AppJsBridge.kt):
@JavascriptInterface
fun promptBiometrics(callbackName: String) {
val biometricPrompt = BiometricPrompt(activity, executor, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric Login")
.setNegativeButtonText("Cancel")
.build()
biometricPrompt.authenticate(promptInfo)
}
Inside your web application's JavaScript interface, you check if the native app shell is active and trigger the biometric prompt:
function loginWithBiometrics() {
if (window.AndroidBridge) {
window.AndroidBridge.promptBiometrics("onBiometricResult");
}
}
// Global callback function to receive auth status
window.onBiometricResult = function(success, token) {
if (success) {
// Authenticate user session with your backend using the decrypted token
fetch('/api/auth/biometric', { method: 'POST', body: JSON.stringify({ token }) })
.then(res => window.location.reload());
}
};
3. Securing Session Tokens
For biometrics to work on subsequent app launches without typing a password, the app must store a secure session token during the initial login. This token should be encrypted and saved in the device's hardware-backed keystore (Android Keystore / iOS Keychain). When the user opens the app, the biometric prompt is shown. Upon scan success, the native app decrypts the token, injects it back into the WebView session, and opens the dashboard.
Conclusion
Integrating biometrics bridges the UX gap between web and native. It provides users with a secure, one-tap login experience that keeps their session active and safe, even if they share or lose their device.



