biometricAuthUtils.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import 'package:appfx/utils/logger.dart';
  2. import 'package:local_auth/local_auth.dart';
  3. import 'package:flutter_secure_storage/flutter_secure_storage.dart';
  4. export 'package:local_auth/local_auth.dart' show BiometricType;
  5. class BioAuthResult {
  6. final bool authed;
  7. final int errorCode;
  8. final String errorReason;
  9. BioAuthResult({
  10. this.authed = false,
  11. this.errorCode = 0,
  12. this.errorReason = '',
  13. });
  14. bool get isAuthed => (errorCode == 0) && authed;
  15. bool get isError => (errorCode < 0);
  16. bool get isBenignError => (errorCode > 0);
  17. }
  18. class BiometricAuthUtils {
  19. bool canCheckBiometrics = false;
  20. List<BiometricType> availableBiometrics = [];
  21. final LocalAuthentication auth = LocalAuthentication();
  22. final FlutterSecureStorage storage = const FlutterSecureStorage();
  23. Future<void> init() async {
  24. try {
  25. canCheckBiometrics = await checkBiometrics();
  26. if (canCheckBiometrics) {
  27. availableBiometrics = await getAvailableBiometrics();
  28. }
  29. } catch (error) {
  30. Log.e('init error: $error');
  31. }
  32. }
  33. bool get isSupportFaceId {
  34. return availableBiometrics.any((type) => type == BiometricType.face);
  35. }
  36. bool get isSupportTouchId {
  37. return availableBiometrics.any((type) => type == BiometricType.fingerprint);
  38. }
  39. // 检查设备是否支持生物识别
  40. Future<bool> checkBiometrics() async {
  41. try {
  42. canCheckBiometrics = await auth.canCheckBiometrics;
  43. return canCheckBiometrics;
  44. } catch (e) {
  45. Log.e('检查设备是否支持生物识别失败: $e');
  46. canCheckBiometrics = false;
  47. return false;
  48. }
  49. }
  50. // 获取可用的生物识别类型
  51. Future<List<BiometricType>> getAvailableBiometrics() async {
  52. try {
  53. availableBiometrics = await auth.getAvailableBiometrics();
  54. return availableBiometrics;
  55. } catch (e) {
  56. Log.e('获取生物识别类型失败: $e');
  57. availableBiometrics = [];
  58. return availableBiometrics;
  59. }
  60. }
  61. // 进行生物识别认证
  62. Future<BioAuthResult> authenticateWithBiometrics(String reason) async {
  63. try {
  64. final bool authed = await auth.authenticate(
  65. localizedReason: reason, // '请进行人脸识别以访问您的密码',
  66. biometricOnly: true,
  67. sensitiveTransaction: true,
  68. persistAcrossBackgrounding: false,
  69. );
  70. return BioAuthResult(authed: authed, errorCode: 0);
  71. } on LocalAuthException catch (e) {
  72. Log.e('biometric LocalAuthException error: $e');
  73. if ((e.code == LocalAuthExceptionCode.timeout) ||
  74. (e.code == LocalAuthExceptionCode.userCanceled) ||
  75. (e.code == LocalAuthExceptionCode.systemCanceled) ||
  76. (e.code == LocalAuthExceptionCode.temporaryLockout)) {
  77. return BioAuthResult(errorCode: 1, errorReason: e.description ?? 'canceled');
  78. } else {
  79. return BioAuthResult(errorCode: -1, errorReason: e.description ?? e.toString());
  80. }
  81. } catch (e) {
  82. Log.e('biometric authenticate error: $e');
  83. return BioAuthResult(errorCode: -1, errorReason: e.toString());
  84. }
  85. }
  86. }