Guardo
Powerful Flutter biometric authentication with automatic lock screen
Seamlessly add biometric authentication to your Flutter apps with automatic lockout handling, customizable lock screens, and smart fallback to device credentials.
Table of Contents
- Key Features
- Installation
- Quick Start
- Usage
- Actions
- Deprecated Methods
- Localization
- Error Handling
- Common Use Cases
- API Reference
- Troubleshooting
- Platform Support
- Contributing
- License
Key Features
Smart Authentication
- Biometric authentication - Support for Face ID, Touch ID, Fingerprint, and Iris scanning
- Automatic fallback - Seamlessly switches to PIN/Pattern/Password when biometrics fail or are locked out
- Smart detection - Automatically bypasses authentication UI when no auth methods are configured on device
- Lockout handling - Intelligent handling of temporary and permanent biometric lockouts with user-friendly messages
Auto-Lock & Security
- Auto-lock timer - Automatically locks app after configurable period of inactivity
- App lifecycle management - Locks when app goes to background, unlocks on return with authentication
- Manual lock control - Programmatically lock/unlock app based on your security requirements
- Session persistence - Maintains authentication state across app launches with sticky authentication
Customizable UI
- Custom lock screens - Build completely custom lock screens or use the provided default design
- Theme support - Automatically adapts to system light/dark theme settings
- Localization - Built-in support for English, Spanish, and Arabic with easy custom language addition
- RTL support - Full right-to-left language support with automatic UI mirroring
Developer Experience
- Simple API - Single widget wrapper for entire app authentication
- Clean namespace - All methods organized under
context.guardo.*
for better code organization - Flexible control - Enable/disable authentication dynamically based on user preferences or app state
- Debug mode - Easily disable authentication during development with a single flag
Installation
dependencies:
guardo: ^1.0.0
Platform Setup
Android
Add to AndroidManifest.xml
:
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
Update your MainActivity to use FlutterFragmentActivity
:
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
// ...
}
iOS
Add to Info.plist
:
<key>NSFaceIDUsageDescription</key>
<string>This app uses Face ID for secure authentication</string>
Quick Start
Wrap your app with Guardo
- that's it!
import 'package:flutter/material.dart';
import 'package:guardo/guardo.dart';
void main() => runApp(
Guardo(
child: MaterialApp(
home: MyHomePage(),
),
),
);
Usage
Basic Configuration
Guardo(
enabled: true, // Enable/disable authentication
config: GuardoConfig(
localizedReason: 'Please authenticate to access the app',
biometricOnly: true,
lockTimeout: Duration(minutes: 5), // Auto-lock after inactivity
),
child: YourApp(),
)
Unified API
All Guardo methods are organized under context.guardo.*
:
// Check authentication status
if (context.guardo.isAuthenticated) {
// User is authenticated
}
// Perform secure action
await context.guardo.action(
onSuccess: () => deleteAccount(),
onFailure: (error) => showError(error),
reason: 'Authenticate to delete account',
);
// Manual lock/unlock
await context.guardo.lockApp();
await context.guardo.unlockApp();
// Check device capabilities
final hasAuth = await context.guardo.hasAuthenticationMethods();
Custom Lock Screen
Guardo(
lockScreen: (context, onUnlock) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.lock, size: 100),
Text('App Locked'),
ElevatedButton(
onPressed: onUnlock,
child: Text('Unlock'),
),
],
),
),
);
},
child: YourApp(),
)
Actions
Actions are secure operations that require authentication before execution. The unified action()
method intelligently handles both synchronous and asynchronous operations, automatically prompting for biometric authentication when needed.
How Actions Work
- Authentication first - Prompts user for biometric/PIN authentication before executing
- Automatic type detection - Detects if your operation is sync or async automatically
- Error handling - Built-in failure callbacks for graceful error management
- Return values - Supports operations that return values with type safety
// Synchronous action - blocks until completion
await context.guardo.action(
onSuccess: () => performAction(),
reason: 'Please authenticate',
);
// Asynchronous action - handles async operations seamlessly
await context.guardo.action(
onSuccess: () async => await uploadData(),
reason: 'Authenticate to upload',
);
// Action with return value - get results from secure operations
final result = await context.guardo.action<String>(
onSuccess: () async => await fetchSecretKey(),
onFailure: (error) => 'default_key',
reason: 'Access encryption key',
);
Deprecated Methods
These methods are still available for backward compatibility but will be removed in a future version. Use the new context.guardo.*
API instead.
Deprecated Method | New Method |
---|---|
context.lockApp() |
context.guardo.lockApp() |
context.unlockApp() |
context.guardo.unlockApp() |
context.resetLockTimer() |
context.guardo.resetLockTimer() |
context.isAuthenticated |
context.guardo.isAuthenticated |
context.isAppLocked |
context.guardo.isAppLocked |
context.isGuardoEnabled() |
context.guardo.isEnabled() |
context.guardoState |
context.guardo.state |
context.secureAction() |
context.guardo.action() |
context.guardoActionWithResult<T>() |
context.guardo.action<T>() |
context.guardoAsyncAction() |
context.guardo.action() with async |
context.guardoAsyncActionWithResult<T>() |
context.guardo.action<T>() with async |
Localization
Built-in Languages
- English (en)
- Spanish (es)
- Arabic (ar)
Setup
MaterialApp(
localizationsDelegates: const [
GuardoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), Locale('es'), Locale('ar'),
],
home: Guardo(child: MyApp()),
)
Custom Languages
Create a custom localization:
class GuardoLocalizationsKo extends GuardoLocalizations {
@override
String get authenticateToUnlock => '잠금을 해제하려면 인증해 주세요';
// ... implement other required strings
}
Error Handling
try {
await context.guardo.action(
onSuccess: () => sensitiveOperation(),
);
} on BiometricLockoutException {
// Handle temporary lockout
showMessage('Too many attempts. Try again later.');
} on BiometricUnavailableException {
// Handle unavailable biometrics
showMessage('Biometrics not available');
}
Common Use Cases
Banking App
// Secure transaction
await context.guardo.action(
onSuccess: () async => await transferMoney(amount),
reason: 'Authenticate to transfer funds',
);
Note-Taking App
// Lock on app background
Guardo(
config: GuardoConfig(
lockTimeout: Duration(seconds: 30),
),
child: NotesApp(),
)
Healthcare App
// View sensitive data
final medicalRecords = await context.guardo.action<List<Record>>(
onSuccess: () async => await fetchMedicalRecords(),
onFailure: (e) => [],
reason: 'Authenticate to view medical records',
);
API Reference
GuardoConfig
Property | Type | Default | Description |
---|---|---|---|
localizedReason |
String |
'Please authenticate...' | Auth prompt message |
biometricOnly |
bool |
true |
Use only biometrics |
lockTimeout |
Duration? |
null |
Auto-lock timeout |
autoCheckOnStart |
bool |
true |
Check auth on start |
Context Extensions
All methods available via context.guardo.*
:
Method | Description |
---|---|
action<T>() |
Execute authenticated action |
lockApp() |
Lock the app manually |
unlockApp() |
Unlock with authentication |
resetLockTimer() |
Reset auto-lock timer |
isAuthenticated |
Check if authenticated |
isEnabled() |
Check if Guardo is enabled |
hasAuthenticationMethods() |
Check if auth methods available |
Troubleshooting
App not locking?
Ensure Guardo
wraps your entire MaterialApp
:
Guardo(
config: GuardoConfig(lockTimeout: Duration(minutes: 5)),
child: MaterialApp(...), // Correct
)
Biometrics not working?
Check device capabilities first:
if (await context.guardo.hasAuthenticationMethods()) {
// Safe to use authentication
}
Debug mode?
Disable authentication during development:
Guardo(
enabled: !kDebugMode, // Disabled in debug mode
child: YourApp(),
)
Platform Support
Platform | Biometric Types | Requirements |
---|---|---|
iOS | Face ID, Touch ID | iOS 9.0+ |
Android | Fingerprint, Face, Iris | API 23+ |
Contributing
We welcome contributions! See our Contributing Guidelines for details.
# Clone the repository
git clone https://github.com/fathialamre/guardo.git
# Run example app
cd example
flutter run
License
MIT License - see the LICENSE file for details.
Made with love for the Flutter community