Local Authentication
A flutter plugin that allows access to Local Authentication / Biometrics on iOS, macOS, Linux, Android and Windows Hello.
📖 Documentation: eaceto.github.io/flutter_local_authentication (setup, guides and API reference)
- 4.1. canAuthenticate
- 4.2. Supported Platforms
Features
-
Detects if biometric authentication can be done in the current platform (canAuthenticate).
-
Triggers platform's native authentication for the current user (authenticate).
-
Read/Write macOS/iOS touchIDAuthenticationAllowableReuseDuration value
-
Localized messages for iOS, macOS, Android and Windows
-
Tells why the user can not authenticate (getAvailability), and which biometrics the device has (getBiometryType)
-
Dismisses the prompt from the app (cancelAuthentication)
-
Errors are an AuthenticationException with the same reason on every platform (canceled, locked out, not enrolled, ...)
Usage
Initialization
Initialize an instance of the plugin, which requires no input parameters.
final _flutterLocalAuthenticationPlugin = FlutterLocalAuthentication();
Localization
At any time a localization model can be applied. The latests applied is used by the plugin when the local authentication is performed.
final localization = LocalizationModel(
promptDialogTitle: "title for dialog",
promptDialogReason: "reason for prompting biometric",
cancelButtonTitle: "cancel"
);
_flutterLocalAuthenticationPlugin.setLocalizationModel(localization);
Querying support and performing Local Authentication
Two functions are available for the core feature of this library:
- canAuthenticate
- authenticate
Depending on each platform the behaviour of canAuthenticate can differ.
bool canAuthenticate;
try {
// Query suppor for Local Authentication
canAuthenticate = await _flutterLocalAuthenticationPlugin.canAuthenticate();
// Setup TouchID Allowable Reuse duration
// It works only in iOS and macOS, but it's safe to call it even on other platforms.
await _flutterLocalAuthenticationPlugin.setTouchIDAuthenticationAllowableReuseDuration(30);
} on Exception catch (error) {
debugPrint("Exception checking support. $error");
canAuthenticate = false;
}
if (canAuthenticate) {
// Perform Local Authentication
_flutterLocalAuthenticationPlugin.authenticate().then((authenticated) {
String result = 'Authenticated: $authenticated';
// handle result
}).catchError((error) {
String result = 'Exception: $error';
// handle error
});
}
Authentication methods
Both canAuthenticate and authenticate accept an optional method, that defines which authenticators the user is allowed to use. Always use the same method on both calls.
- AuthenticationMethod.biometricsOnly (default): biometrics only.
- AuthenticationMethod.biometricsOrDeviceCredential: biometrics, falling back to the device PIN, pattern, passcode or password. Users without enrolled biometrics can authenticate.
- AuthenticationMethod.deviceCredentialOnly: device PIN, pattern, passcode or password only.
const method = AuthenticationMethod.biometricsOrDeviceCredential;
if (await _flutterLocalAuthenticationPlugin.canAuthenticate(method: method)) {
await _flutterLocalAuthenticationPlugin.authenticate(method: method);
}
When a method is not supported by the platform canAuthenticate returns false, getAvailability returns unsupportedMethod, and authenticate throws an AuthenticationException with reason unsupportedMethod.
| Method | Android | iOS | macOS | Linux | Windows |
|---|---|---|---|---|---|
| biometricsOnly | ✅ | ✅ | ✅ | ✅ | ✅ |
| biometricsOrDeviceCredential | ✅ | ✅ | ✅ | ❌ | ✅ |
| deviceCredentialOnly | ✅ API 30 or newer | ✅ | ✅ | ❌ | ✅ |
Availability, biometry type and errors
// Why the user can, or can not, authenticate
final availability = await _flutterLocalAuthenticationPlugin.getAvailability(method: method);
if (availability == AuthenticationAvailability.notEnrolled) {
// ask the user to enroll biometrics, or allow the device credential
}
// Label the UI: face, fingerprint, iris, multiple or none
final biometryType = await _flutterLocalAuthenticationPlugin.getBiometryType();
try {
await _flutterLocalAuthenticationPlugin.authenticate(method: method);
} on AuthenticationException catch (error) {
if (!error.isCanceled) {
// error.reason: lockedOut, notEnrolled, credentialNotSet, failed, ...
}
}
// Dismiss the prompt, for example when the app moves to the background
await _flutterLocalAuthenticationPlugin.cancelAuthentication();
Considerations
canAuthenticate
The function canAuthenticate will return true in the following scenarios, depending on the authentication method.
-
Android: true if BiometricManager returns that it can authenticate with the allowed authenticators:
- biometricsOnly: BIOMETRIC_STRONG or BIOMETRIC_WEAK
- biometricsOrDeviceCredential: BIOMETRIC_STRONG, BIOMETRIC_WEAK or DEVICE_CREDENTIAL
- deviceCredentialOnly: DEVICE_CREDENTIAL
-
iOS and macOS: true if LAContext.canEvaluatePolicy returns true for the policy:
- biometricsOnly: deviceOwnerAuthenticationWithBiometrics
- biometricsOrDeviceCredential and deviceCredentialOnly: deviceOwnerAuthentication (a passcode / password is set)
-
linux: true if the method is biometricsOnly, fprintd is installed and the user has enrolled fingerprints.
Supported platforms
- iOS 15 or newer
- macOS 12 or newer
- Linux (requires libfprint)
- Android 7.0 (API 24) or newer
- Windows 10 version 1607 or newer with Windows Hello configured
Publishing a new version
The package is published to pub.dev by hand, from a clean checkout of main.
1. Bump the version
The version lives in four files, keep them in sync:
pubspec.yaml→version:android/build.gradle→versiondarwin/flutter_local_authentication.podspec→s.versionCHANGELOG.md→ add a## x.y.zsection at the top
Follow semantic versioning: a change in the public Dart API or in a minimum platform version is a major bump.
2. Verify
flutter analyze
flutter test
# Every platform of the example app must build
cd example
flutter build apk --debug
flutter build ios --debug --no-codesign
flutter build macos --debug
cd ..
# Checks the package, and lists exactly what will be uploaded
flutter pub publish --dry-run
The dry-run must report no warnings and an archive of a few hundred KB. Anything bigger means a build artifact leaked in: add it to .pubignore (it replaces .gitignore when publishing, so every rule has to be there).
3. Commit, tag and publish
git commit -am "Release x.y.z"
git tag vx.y.z
git push origin main vx.y.z
flutter pub publish
flutter pub publish opens the browser to sign in to pub.dev with an account that is an uploader of the package, then asks to confirm the upload. A version can not be re-published, so make sure the dry-run is clean first.
4. Release on GitHub
Create a release from the tag, with the CHANGELOG.md section as its notes. The documentation site is rebuilt by the docs workflow on every push to main.