[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-autenticazione-biometrica-in-flutter-con-local-auth-impronte-e-face-id":3,"comments-article-autenticazione-biometrica-in-flutter-con-local-auth-impronte-e-face-id":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},28,"Autenticazione biometrica in Flutter con local_auth: impronte e Face ID","autenticazione-biometrica-in-flutter-con-local-auth-impronte-e-face-id","Impara a integrare Face ID, Touch ID e l'autenticazione con impronta digitale nelle tue app Flutter usando il pacchetto local_auth, gestendo correttamente errori e configurazioni native.","## Perché l'autenticazione biometrica\n\nL'autenticazione biometrica è diventata uno standard di fatto per proteggere l'accesso ad aree sensibili delle applicazioni mobili: dati bancari, note private, gestori di password. Rispetto a un PIN, offre un'esperienza utente più fluida e un buon livello di sicurezza, poiché i dati biometrici non lasciano mai il *secure enclave* del dispositivo.\n\nIn Flutter, il pacchetto ufficiale [`local_auth`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Flocal_auth) permette di sfruttare Face ID, Touch ID e il riconoscimento tramite impronta digitale con poche righe di codice.\n\n## Installazione\n\nAggiungi le dipendenze al file `pubspec.yaml`:\n\n```yaml\ndependencies:\n  local_auth: ^2.3.0\n  local_auth_android: ^1.0.46\n  local_auth_ios: ^1.1.7\n```\n\n## Configurazione nativa\n\n### iOS\n\nAggiungi la chiave `NSFaceIDUsageDescription` al file `ios\u002FRunner\u002FInfo.plist`, altrimenti l'app verrà rifiutata dall'App Store:\n\n```xml\n\u003Ckey>NSFaceIDUsageDescription\u003C\u002Fkey>\n\u003Cstring>Utilizziamo Face ID per proteggere l'accesso ai tuoi dati.\u003C\u002Fstring>\n```\n\n### Android\n\nNel file `android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml` verifica il permesso:\n\n```xml\n\u003Cuses-permission android:name=\"android.permission.USE_BIOMETRIC\"\u002F>\n```\n\nInoltre la `MainActivity` deve estendere `FlutterFragmentActivity` (e non `FlutterActivity`), altrimenti la chiamata biometrica va in crash:\n\n```kotlin\nimport io.flutter.embedding.android.FlutterFragmentActivity\n\nclass MainActivity: FlutterFragmentActivity()\n```\n\n## Verificare la disponibilità\n\nPrima di autenticare, è buona norma controllare se il dispositivo supporta la biometria e quali metodi sono disponibili:\n\n```dart\nimport 'package:local_auth\u002Flocal_auth.dart';\n\nfinal LocalAuthentication auth = LocalAuthentication();\n\nFuture\u003Cbool> isBiometricAvailable() async {\n  final bool canCheck = await auth.canCheckBiometrics;\n  final bool isSupported = await auth.isDeviceSupported();\n  return canCheck && isSupported;\n}\n\nFuture\u003CList\u003CBiometricType>> getAvailableBiometrics() async {\n  return await auth.getAvailableBiometrics();\n}\n```\n\nIl metodo `getAvailableBiometrics()` restituisce una lista di tipi come `BiometricType.face`, `BiometricType.fingerprint` o `BiometricType.strong`, utile per mostrare l'icona corretta nell'interfaccia.\n\n## Eseguire l'autenticazione\n\nIl cuore del pacchetto è il metodo `authenticate`:\n\n```dart\nFuture\u003Cbool> authenticate() async {\n  try {\n    return await auth.authenticate(\n      localizedReason: 'Conferma la tua identità per continuare',\n      options: const AuthenticationOptions(\n        biometricOnly: false, \u002F\u002F consente il fallback a PIN\u002Fpattern\n        stickyAuth: true,     \u002F\u002F riprende dopo un'interruzione\n        useErrorDialogs: true,\n      ),\n    );\n  } on PlatformException catch (e) {\n    debugPrint('Errore biometrico: ${e.code} - ${e.message}');\n    return false;\n  }\n}\n```\n\nAlcune opzioni importanti:\n\n- **`biometricOnly`**: se `true`, esclude il fallback al codice di sblocco del dispositivo.\n- **`stickyAuth`**: mantiene attiva l'autenticazione se l'app va in background (ad esempio quando l'utente cambia app per aprire un'altra applicazione).\n- **`useErrorDialogs`**: mostra le finestre di dialogo di sistema per situazioni come l'assenza di biometria registrata.\n\n## Gestione degli errori\n\nLe `PlatformException` restituiscono codici specifici che è opportuno gestire. I più comuni sono definiti nella classe `auth_error`:\n\n```dart\nimport 'package:local_auth\u002Ferror_codes.dart' as auth_error;\n\ntry {\n  await auth.authenticate(localizedReason: 'Accedi');\n} on PlatformException catch (e) {\n  switch (e.code) {\n    case auth_error.notAvailable:\n      \u002F\u002F Nessuna biometria disponibile sul dispositivo\n      break;\n    case auth_error.notEnrolled:\n      \u002F\u002F L'utente non ha registrato impronte o volto\n      break;\n    case auth_error.lockedOut:\n    case auth_error.permanentlyLockedOut:\n      \u002F\u002F Troppi tentativi falliti\n      break;\n  }\n}\n```\n\n## Un esempio completo\n\n```dart\nclass AuthGate extends StatefulWidget {\n  const AuthGate({super.key});\n\n  @override\n  State\u003CAuthGate> createState() => _AuthGateState();\n}\n\nclass _AuthGateState extends State\u003CAuthGate> {\n  final LocalAuthentication _auth = LocalAuthentication();\n  bool _autenticato = false;\n\n  Future\u003Cvoid> _sblocca() async {\n    final bool disponibile =\n        await _auth.canCheckBiometrics && await _auth.isDeviceSupported();\n    if (!disponibile) return;\n\n    try {\n      final ok = await _auth.authenticate(\n        localizedReason: 'Sblocca per accedere ai tuoi dati',\n        options: const AuthenticationOptions(stickyAuth: true),\n      );\n      if (mounted) setState(() => _autenticato = ok);\n    } on PlatformException catch (e) {\n      debugPrint('Errore: ${e.code}');\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    if (_autenticato) {\n      return const HomeScreen();\n    }\n    return Scaffold(\n      body: Center(\n        child: ElevatedButton.icon(\n          onPressed: _sblocca,\n          icon: const Icon(Icons.fingerprint),\n          label: const Text('Sblocca app'),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## Best practice\n\n- **Non affidare la sicurezza solo alla biometria**: usala come *gate* di accesso, ma conserva i dati sensibili con soluzioni come `flutter_secure_storage`.\n- **Offri sempre un'alternativa**: mantieni un metodo di fallback (PIN dell'app o codice del dispositivo) per gli utenti senza biometria registrata.\n- **Ri-autentica dopo il background**: per app critiche, richiedi nuovamente l'autenticazione quando l'app torna in foreground usando il `WidgetsBindingObserver`.\n- **Rispetta la privacy**: comunica chiaramente all'utente perché richiedi l'accesso biometrico tramite il parametro `localizedReason`.\n\n## Conclusioni\n\nCon `local_auth` integrare Face ID, Touch ID e impronte digitali in Flutter richiede poche righe di codice, ma la parte più delicata riguarda la configurazione nativa e la gestione robusta degli errori. Combinando l'autenticazione biometrica con uno storage sicuro otterrai un livello di protezione adeguato per le informazioni più sensibili dei tuoi utenti.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F87aae66e-eea0-425e-ab22-2f939b0dd1bc.jpg",null,"published","2026-07-02T04:00:40+00:00","Autenticazione biometrica in Flutter con local_auth","Guida pratica per integrare Face ID, Touch ID e impronte digitali in Flutter con local_auth: configurazione nativa, esempi e gestione degli errori.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219603668]