Step 1: Add the local_auth and get package Open your project’s pubspec.yaml file and add the local_auth and get dependency under the dependencies section:
dependencies:
flutter:
sdk: flutter
local_auth: ^2.1.6
get: ^4.6.5
Run flutter pub get to fetch the package.
Step 2: Create a GetX controller class to handle Biometric Authentication In this example, the BiometricController handles the biometric authentication logic using the local_auth package. It checks for biometric support, retrieves available biometric types, and performs authentication. The isAuthenticated variable is observed using RxBool from GetX, allowing you to react to changes in the authentication status.
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
class BiometricController extends GetxController {
final LocalAuthentication _localAuth = LocalAuthentication();
RxBool isAuthenticated = false.obs;
}
Step 3: Check device support with available Biometrics The checkBiometrics() method is a asynchronous function that checks for the availability of biometric authentication on the device and retrieves the available biometric types if they are supported.
Future<void> checkBiometrics() async {
bool canCheckBiometrics;
try {
canCheckBiometrics = await _localAuth.canCheckBiometrics;
} catch (e) {
print(e);
return;
}
if (!canCheckBiometrics) {
// Biometrics not available on this device
return;
}
List<BiometricType> availableBiometrics = await _localAuth.getAvailableBiometrics();
print('Available biometrics: $availableBiometrics');
}
Step 4: Authenticate with biometrics The authenticate() method initiates the biometric authentication process using the authenticate method from the local_auth package. It takes into account the following parameters:
localizedReason: A message displayed to the user, explaining the reason for authentication, such as "Authenticate to access the app" options: Authentication options that can be set using AuthenticationOptions. In this case, the options are configured with the following settings: stickyAuth: Specifies whether the authentication should remain sticky, meaning the user won't need to authenticate again until the app is closed. biometricOnly: Restricts the authentication to biometric methods only, such as fingerprint or face recognition. useErrorDialogs: Determines whether to display system error dialogs if the authentication fails. Upon completion of the authentication process, the resulting boolean value is stored in the authenticated variable. If the authentication is successful, the isAuthenticated value is updated accordingly. You can use this value to control the app logic based on the authentication status.
Future<void> authenticate() async {
try {
bool authenticated = await _localAuth.authenticate(
localizedReason: 'Authenticate to access the app',
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
useErrorDialogs: true,
),
);
isAuthenticated.value = authenticated;
if (authenticated) {
// Biometric authentication successful, proceed with your app logic
} else {
// Biometric authentication failed or was canceled
}
} catch (e) {
print(e);
}
}
Step 5: Putting it all together in BiometricController class
import 'package:get/get.dart';
import 'package:local_auth/local_auth.dart';
class BiometricController extends GetxController {
final LocalAuthentication _localAuth = LocalAuthentication();
RxBool isAuthenticated = false.obs;
Future<void> checkBiometrics() async {
bool canCheckBiometrics;
try {
canCheckBiometrics = await _localAuth.canCheckBiometrics;
} catch (e) {
print(e);
return;
}
if (!canCheckBiometrics) {
// Biometrics not available on this device
return;
}
List<BiometricType> availableBiometrics = await _localAuth.getAvailableBiometrics();
print('Available biometrics: $availableBiometrics');
}
Future<void> authenticate() async {
try {
bool authenticated = await _localAuth.authenticate(
localizedReason: 'Authenticate to access the app',
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
useErrorDialogs: true,
),
);
isAuthenticated.value = authenticated;
if (authenticated) {
// Biometric authentication successful, proceed with your app logic
} else {
// Biometric authentication failed or was canceled
}
} catch (e) {
print(e);
}
}
}
Step 6: Initialise the controller and call the methods in your widget/screen
import 'package:ariana/controller/biometric_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class BiometricScreen extends StatelessWidget {
final BiometricController _biometricController =
Get.put(BiometricController());
BiometricScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Biometric Authentication'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
await _biometricController.checkBiometrics();
if (_biometricController.isAuthenticated.value) {
// Biometric authentication successful, proceed with your app logic
} else {
// Biometric authentication failed or was canceled
await _biometricController.authenticate();
}
},
child: Text('Authenticate with Biometrics'),
),
),
);
}
}
Conclusion This blog provides a concise and practical guide to implementing Biometric Authentication in Flutter using the local_auth package and a GetX controller. By following the step-by-step instructions, you can easily integrate biometric support, retrieve available biometric types, and handle authentication processes.
Key takeaways from this blog include:
Understanding how to check for biometric support and retrieve available biometric types on the device. Initiating the biometric authentication process with localized reasons and authentication options. Handling authentication success, failure, and cancellation effectively. Organising and maintaining clean code using a separate GetX controller for biometric authentication logic. By following the step-by-step guide and understanding the concepts presented in this blog, you now have the knowledge and tools to implement secure and user-friendly biometric authentication in your Flutter applications.