Flutter本地身份验证插件local_auth_android_credentials的使用

Flutter本地身份验证插件local_auth_android_credentials的使用

该Android实现是为local_auth包提供的。

使用方法

此插件是被官方推荐的插件之一,这意味着你可以直接使用local_auth。当你这样做时,此插件将自动包含在你的应用中。


示例代码

以下是使用local_auth_android_credentials插件进行本地身份验证的完整示例。

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth_android_credentials/local_auth_android_credentials.dart';
import 'package:local_auth_platform_interface/local_auth_platform_interface.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  _SupportState _supportState = _SupportState.unknown;
  bool? _deviceSupportsBiometrics;
  List<BiometricType>? _enrolledBiometrics;
  String _authorized = 'Not Authorized';
  bool _isAuthenticating = false;

  @override
  void initState() {
    super.initState();
    LocalAuthPlatform.instance.isDeviceSupported().then(
          (bool isSupported) => setState(() => _supportState = isSupported
              ? _SupportState.supported
              : _SupportState.unsupported),
        );
  }

  Future<void> _checkBiometrics() async {
    late bool deviceSupportsBiometrics;
    try {
      deviceSupportsBiometrics =
          await LocalAuthPlatform.instance.deviceSupportsBiometrics();
    } on PlatformException catch (e) {
      deviceSupportsBiometrics = false;
      print(e);
    }
    if (!mounted) {
      return;
    }

    setState(() {
      _deviceSupportsBiometrics = deviceSupportsBiometrics;
    });
  }

  Future<void> _getEnrolledBiometrics() async {
    late List<BiometricType> availableBiometrics;
    try {
      availableBiometrics =
          await LocalAuthPlatform.instance.getEnrolledBiometrics();
    } on PlatformException catch (e) {
      availableBiometrics = [];
      print(e);
    }
    if (!mounted) {
      return;
    }

    setState(() {
      _enrolledBiometrics = availableBiometrics;
    });
  }

  Future<void> _authenticate() async {
    bool authenticated = false;
    try {
      setState(() {
        _isAuthenticating = true;
        _authorized = 'Authenticating';
      });
      authenticated = await LocalAuthPlatform.instance.authenticate(
        localizedReason: 'Let OS determine authentication method',
        authMessages: [const AndroidAuthMessages()],
        options: const AuthenticationOptions(
          stickyAuth: true,
        ),
      );
      setState(() {
        _isAuthenticating = false;
      });
    } on PlatformException catch (e) {
      print(e);
      setState(() {
        _isAuthenticating = false;
        _authorized = 'Error - ${e.message}';
      });
      return;
    }
    if (!mounted) {
      return;
    }

    setState(
        () => _authorized = authenticated ? 'Authorized' : 'Not Authorized');
  }

  Future<void> _authenticateWithBiometrics() async {
    bool authenticated = false;
    try {
      setState(() {
        _isAuthenticating = true;
        _authorized = 'Authenticating';
      });
      authenticated = await LocalAuthPlatform.instance.authenticate(
        localizedReason:
            'Scan your fingerprint (or face or whatever) to authenticate',
        authMessages: [const AndroidAuthMessages()],
        options: const AuthenticationOptions(
          stickyAuth: true,
          biometricOnly: true,
        ),
      );
      setState(() {
        _isAuthenticating = false;
        _authorized = 'Authenticating';
      });
    } on PlatformException catch (e) {
      print(e);
      setState(() {
        _isAuthenticating = false;
        _authorized = 'Error - ${e.message}';
      });
      return;
    }
    if (!mounted) {
      return;
    }

    final String message = authenticated ? 'Authorized' : 'Not Authorized';
    setState(() {
      _authorized = message;
    });
  }

  Future<void> _cancelAuthentication() async {
    await LocalAuthPlatform.instance.stopAuthentication();
    setState(() => _isAuthenticating = false);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: ListView(
          padding: const EdgeInsets.only(top: 30),
          children: [
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                if (_supportState == _SupportState.unknown)
                  const CircularProgressIndicator()
                else if (_supportState == _SupportState.supported)
                  const Text('This device is supported')
                else
                  const Text('This device is not supported'),
                const Divider(height: 100),
                Text(
                    'Device supports biometrics: $_deviceSupportsBiometrics\n'),
                ElevatedButton(
                  onPressed: _checkBiometrics,
                  child: const Text('Check biometrics'),
                ),
                const Divider(height: 100),
                Text('Enrolled biometrics: $_enrolledBiometrics\n'),
                ElevatedButton(
                  onPressed: _getEnrolledBiometrics,
                  child: const Text('Get enrolled biometrics'),
                ),
                const Divider(height: 100),
                Text('Current State: $_authorized\n'),
                if (_isAuthenticating)
                  ElevatedButton(
                    onPressed: _cancelAuthentication,
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        Text('Cancel Authentication'),
                        Icon(Icons.cancel),
                      ],
                    ),
                  )
                else
                  Column(
                    children: [
                      ElevatedButton(
                        onPressed: _authenticate,
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: const [
                            Text('Authenticate'),
                            Icon(Icons.perm_device_information),
                          ],
                        ),
                      ),
                      ElevatedButton(
                        onPressed: _authenticateWithBiometrics,
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Text(_isAuthenticating
                                ? 'Cancel'
                                : 'Authenticate: biometrics only'),
                            const Icon(Icons.fingerprint),
                          ],
                        ),
                      ),
                    ],
                  ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

enum _SupportState {
  unknown,
  supported,
  unsupported,
}

代码说明

  • 检查设备是否支持生物识别功能

    Future<void> _checkBiometrics() async {
      late bool deviceSupportsBiometrics;
      try {
        deviceSupportsBiometrics =
            await LocalAuthPlatform.instance.deviceSupportsBiometrics();
      } on PlatformException catch (e) {
        deviceSupportsBiometrics = false;
        print(e);
      }
      if (!mounted) {
        return;
      }
    
      setState(() {
        _deviceSupportsBiometrics = deviceSupportsBiometrics;
      });
    }
    
  • 获取已注册的生物识别类型

    Future<void> _getEnrolledBiometrics() async {
      late List<BiometricType> availableBiometrics;
      try {
        availableBiometrics =
            await LocalAuthPlatform.instance.getEnrolledBiometrics();
      } on PlatformException catch (e) {
        availableBiometrics = [];
        print(e);
      }
      if (!mounted) {
        return;
      }
    
      setState(() {
        _enrolledBiometrics = availableBiometrics;
      });
    }
    
  • 执行身份验证

    Future<void> _authenticate() async {
      bool authenticated = false;
      try {
        setState(() {
          _isAuthenticating = true;
          _authorized = 'Authenticating';
        });
        authenticated = await LocalAuthPlatform.instance.authenticate(
          localizedReason: 'Let OS determine authentication method',
          authMessages: [const AndroidAuthMessages()],
          options: const AuthenticationOptions(
            stickyAuth: true,
          ),
        );
        setState(() {
          _isAuthenticating = false;
        });
      } on PlatformException catch (e) {
        print(e);
        setState(() {
          _isAuthenticating = false;
          _authorized = 'Error - ${e.message}';
        });
        return;
      }
      if (!mounted) {
        return;
      }
    
      setState(
          () => _authorized = authenticated ? 'Authorized' : 'Not Authorized');
    }
    
  • 仅使用生物识别进行身份验证

    Future<void> _authenticateWithBiometrics() async {
      bool authenticated = false;
      try {
        setState(() {
          _isAuthenticating = true;
          _authorized = 'Authenticating';
        });
        authenticated = await LocalAuthPlatform.instance.authenticate(
          localizedReason:
              'Scan your fingerprint (or face or whatever) to authenticate',
          authMessages: [const AndroidAuthMessages()],
          options: const AuthenticationOptions(
            stickyAuth: true,
            biometricOnly: true,
          ),
        );
        setState(() {
          _isAuthenticating = false;
          _authorized = 'Authenticating';
        });
      } on PlatformException catch (e) {
        print(e);
        setState(() {
          _isAuthenticating = false;
          _authorized = 'Error - ${e.message}';
        });
        return;
      }
      if (!mounted) {
        return;
      }
    
      final String message = authenticated ? 'Authorized' : 'Not Authorized';
      setState(() {
        _authorized = message;
      });
    }
    
  • 取消身份验证

    Future<void> _cancelAuthentication() async {
      await LocalAuthPlatform.instance.stopAuthentication();
      setState(() => _isAuthenticating = false);
    }
    

更多关于Flutter本地身份验证插件local_auth_android_credentials的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter本地身份验证插件local_auth_android_credentials的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


local_auth_android_credentials 是一个 Flutter 插件,用于在 Android 设备上进行本地身份验证,它支持使用生物识别(如指纹、面部识别)和密码等认证方式。这个插件是对 local_auth 插件的扩展,专门为 Android 平台提供了更多的功能。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 local_auth_android_credentials 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  local_auth: ^2.0.0
  local_auth_android_credentials: ^0.0.1

然后运行 flutter pub get 来获取依赖。

2. 配置 Android 项目

android/app/build.gradle 文件中,确保 minSdkVersion 至少为 21:

android {
    ...
    defaultConfig {
        minSdkVersion 21
        ...
    }
    ...
}

3. 使用插件

以下是一个简单的示例,展示如何使用 local_auth_android_credentials 插件进行身份验证。

import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:local_auth_android_credentials/local_auth_android_credentials.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LocalAuthScreen(),
    );
  }
}

class LocalAuthScreen extends StatefulWidget {
  @override
  _LocalAuthScreenState createState() => _LocalAuthScreenState();
}

class _LocalAuthScreenState extends State<LocalAuthScreen> {
  final LocalAuthentication _localAuth = LocalAuthentication();

  Future<void> _authenticate() async {
    bool authenticated = false;
    try {
      authenticated = await _localAuth.authenticate(
        localizedReason: '请验证身份以继续',
        authMessages: [
          AndroidAuthMessages(
            biometricHint: "使用生物识别进行验证",
            biometricNotRecognized: "生物识别未识别",
            biometricRequiredTitle: "需要生物识别",
            biometricSuccess: "生物识别成功",
            cancelButton: "取消",
            deviceCredentialsRequiredTitle: "需要设备凭证",
            deviceCredentialsSetupDescription: "设置设备凭证以继续",
            goToSettingsButton: "前往设置",
            goToSettingsDescription: "请前往设置以启用生物识别",
            signInTitle: "登录",
          ),
        ],
        options: AuthenticationOptions(
          biometricOnly: false, // 允许使用密码等其他方式
          useErrorDialogs: true, // 使用系统错误对话框
          stickyAuth: true, // 保持认证状态
        ),
      );
    } catch (e) {
      print("认证失败: $e");
    }

    if (authenticated) {
      // 认证成功
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('认证成功')),
      );
    } else {
      // 认证失败
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('认证失败')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('本地身份验证'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _authenticate,
          child: Text('进行身份验证'),
        ),
      ),
    );
  }
}

4. 解释代码

  • LocalAuthenticationlocal_auth 插件的核心类,用于执行身份验证。
  • authenticate 方法用于启动身份验证流程。你可以通过 localizedReason 参数提供验证的原因。
  • AndroidAuthMessages 用于自定义 Android 平台上的验证消息。
  • AuthenticationOptions 用于配置认证选项,例如是否仅使用生物识别、是否使用系统错误对话框等。

5. 注意事项

  • 确保设备支持生物识别功能,并且在系统设置中已经启用了生物识别。
  • 如果设备不支持生物识别,local_auth 插件会回退到使用设备密码进行验证。

6. 处理权限

在某些情况下,你可能需要请求生物识别权限。你可以在 AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
回到顶部