Biometric authentication is a modern security feature that enhances user experience by allowing users to authenticate using their biological characteristics such as fingerprint, face, or iris scan. Implementing biometric authentication in Flutter applications can significantly improve security while providing a seamless login experience.
What is Biometric Authentication?
Biometric authentication uses unique biological traits to verify a user’s identity. It is considered more secure than traditional password-based authentication since biometrics are difficult to replicate or steal.
Why Use Biometric Authentication in Flutter?
- Enhanced Security: Adds a layer of security that is difficult to compromise.
- Improved User Experience: Provides a quick and easy way for users to authenticate.
- Modern Authentication Method: Aligns with contemporary security standards.
How to Implement Biometric Authentication in Flutter
To implement biometric authentication in Flutter, we use the local_auth
package, which provides the necessary functionalities to access the device’s biometric features.
Step 1: Add the local_auth
Dependency
Add the local_auth
package to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
local_auth: ^2.1.7
After adding the dependency, run flutter pub get
in your terminal.
Step 2: Configure Native Platforms
For Android and iOS, some platform-specific configurations are needed.
Android Configuration
Modify your android/app/build.gradle
file. Set the minSdkVersion
to 23 or higher and add BiometricPrompt.AUTHENTICATE_WEAK
in the keyguardManager line. Without that Android emulator (api < 30) can be unstable.
android {
compileSdkVersion 33
defaultConfig {
applicationId "your_application_id"
minSdkVersion 23
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
...
}
Add the following permission to your AndroidManifest.xml
file (located in android/app/src/main
):
iOS Configuration
Add the following entry to your Info.plist
file (located in ios/Runner
):
NSFaceIDUsageDescription
Why is my app authenticating using face id?
This key describes why your app wants to use Face ID. The string will be displayed to the user when Face ID is requested for the first time. If you plan on supporting iOS versions prior to 11.0 then also add:
Privacy - Face ID Usage Description
Why is my app authenticating using face id?
Step 3: Implement Biometric Authentication Logic
Now, let’s implement the Dart code for biometric authentication.
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Biometric Authentication Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BiometricAuthScreen(),
);
}
}
class BiometricAuthScreen extends StatefulWidget {
@override
_BiometricAuthScreenState createState() => _BiometricAuthScreenState();
}
class _BiometricAuthScreenState extends State {
final LocalAuthentication auth = LocalAuthentication();
bool _canCheckBiometrics = false;
String _authorized = 'Not Authorized';
@override
void initState() {
super.initState();
_checkBiometrics();
}
Future _checkBiometrics() async {
bool canCheck = false;
try {
canCheck = await auth.canCheckBiometrics;
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_canCheckBiometrics = canCheck;
});
}
Future _authenticate() async {
bool authenticated = false;
try {
setState(() {
_authorized = 'Authenticating';
});
authenticated = await auth.authenticate(
localizedReason: 'Scan your fingerprint to authenticate',
options: const AuthenticationOptions(
stickyAuth: true,
),
);
setState(() {
_authorized = authenticated ? 'Authorized' : 'Not Authorized';
});
} on PlatformException catch (e) {
print(e);
setState(() {
_authorized = 'Error - ${e.message}';
});
return;
}
if (!mounted) return;
final String message = authenticated ? 'Authorized' : 'Not Authorized';
print(message);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Biometric Authentication'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Can check biometrics: $_canCheckBiometrics\n'),
Text('Current State: $_authorized\n'),
ElevatedButton(
onPressed: _authenticate,
child: Text('Authenticate'),
),
],
),
),
);
}
}
Explanation:
- We initialize
LocalAuthentication
and define necessary variables to hold the state of biometric checks. - The
_checkBiometrics
method checks if the device supports biometric authentication. - The
_authenticate
method triggers the biometric authentication process usingauth.authenticate
. - The UI displays the current authentication status and provides a button to trigger authentication.
Explanation of Code
- Import Statements:
import 'package:flutter/material.dart';
: Imports the necessary Flutter widgets.import 'package:local_auth/local_auth.dart';
: Imports thelocal_auth
plugin.import 'package:flutter/services.dart';
: Provides access to platform-specific services.- MyApp Class:
- Sets up the basic MaterialApp.
- The home is set to
BiometricAuthScreen
, which is where the main logic resides. - BiometricAuthScreen Class:
- This StatefulWidget class creates a simple screen for biometric authentication.
- _BiometricAuthScreenState Class:
-
Variables:
final LocalAuthentication auth = LocalAuthentication();
: Initializes an instance ofLocalAuthentication
.bool _canCheckBiometrics = false;
: A boolean to store whether the device can check biometrics.String _authorized = 'Not Authorized';
: A string to store the authentication state.
-
initState Method:
- Calls
_checkBiometrics()
when the widget is initialized.
- Calls
- _checkBiometrics Method:
- Asynchronously checks if the device can perform biometric authentication.
- It sets
_canCheckBiometrics
to true or false based on the check. - Error Handling: Catches platform exceptions in case the check fails.
- _authenticate Method:
- Asynchronously authenticates the user using biometrics.
- Updates the UI state:
- Sets
_authorized
to ‘Authenticating’ before starting. - If authentication succeeds, sets
_authorized
to ‘Authorized’. - If authentication fails, sets
_authorized
to ‘Not Authorized’.
- Sets
- Configuration:
- Calls auth.authenticate with the message ‘Scan your fingerprint to authenticate’.
- Uses
AuthenticationOptions
to specifystickyAuth: true
, which keeps the authentication session active.
- Error Handling:
- Handles platform exceptions if authentication fails.
- Sets _authorized to an error message.
- Logging:
- Prints the authentication message to the console.
- build Method:
- Builds the UI for the authentication screen.
- Displayes Text widgets:
- Shows if the device can check biometrics (
_canCheckBiometrics
). - Shows the current authentication state (
_authorized
).
- Shows if the device can check biometrics (
- Button Widget: Creates an ElevatedButton that triggers the
_authenticate()
method when pressed.
Conclusion
Implementing biometric authentication in Flutter applications enhances security and improves user experience. The local_auth
package simplifies the process, providing a secure and modern authentication method. Follow these steps to integrate biometric authentication seamlessly into your Flutter apps, ensuring a secure and user-friendly login experience.