Flutter本地身份验证签名插件local_auth_signature的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter本地身份验证签名插件local_auth_signature的使用

local_auth_signature 插件用于在Android和iOS设备上生成密钥对并进行签名(使用NIST P-256 EC密钥对和ECDSA算法)。

截图

开始使用

要开始使用此插件,首先确保将其添加为Flutter项目的依赖项:

dependencies:
  local_auth_signature: "^1.0.12"

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

使用方法

Flutter

创建新实例

final _localAuthSignature = LocalAuthSignature.instance;

定义密钥

final _key = 'com.prongbang.signx.key';

检查指纹或生物识别是否已更改

  • Android
final status = await _localAuthSignature.isBiometricChanged(_key);
  • iOS
try {
    final signature = await _localAuthSignature.sign(_key, androidPrompt, iosPrompt);
} on PlatformException catch (e) {
  // TODO 检查异常代码
}

创建密钥对

try {
    final publicKey = await _localAuthSignature.createKeyPair(
        _key,
        AndroidPromptInfo(
            title: 'BIOMETRIC',
            subtitle: 'Please allow biometric',
            negativeButton: 'CANCEL',
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
    );
    print('publicKey: $publicKey');
} on PlatformException catch (e) {
  print('PlatformException: ${e.code}');
}

签名

final _payload = 'Hello';
try {
    final signature = await _localAuthSignature.sign(
        _key,
        _payload,
        AndroidPromptInfo(
            title: 'BIOMETRIC',
            subtitle: 'Please allow biometric',
            negativeButton: 'CANCEL',
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
    );
    print('signature: $signature');
} on PlatformException catch (e) {
  print('PlatformException: ${e.code}');
}

验证签名

try {
    final verified = await _localAuthSignature.verify(
        _key,
        _payload,
        _signature!,
        AndroidPromptInfo(
            title: 'BIOMETRIC',
            subtitle: 'Please allow biometric',
            negativeButton: 'CANCEL',
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
    );
    print('verified: $verified');
} on PlatformException catch (e) {
    print('PlatformException: ${e.code}');
}

Android

更新 MainActivity.kt 文件

import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity : FlutterFragmentActivity()

AndroidManifest.xml 中添加权限

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

添加 JitPack Maven 仓库

buildscript {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

iOS

info.plist 中添加隐私描述

<key>NSFaceIDUsageDescription</key>
<string>This application wants to access your TouchID or FaceID</string>

示例代码

以下是完整的示例代码,演示了如何使用 local_auth_signature 插件创建密钥对、签名和验证签名。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth_signature/local_auth_signature.dart';
import 'package:local_auth_signature_example/card_box.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _localAuthSignature = LocalAuthSignature.instance;
  final _key = 'com.prongbang.test.key';
  final _payload = 'Hello';
  String? _publicKey = '';
  String? _signature = 'MEUCIBIcOQng5BqDg9tOjayHDMPgiZT48bWJ0AzkSM0WGVcmAiEAkEGVzlZeJuJCz2IUnqJ/c1zzla1TErcnyU1nzkkN/dA=';
  String? _verified = '';
  String? _status = '';

  void _checkIsBiometricChanged() async {
    final status = await _localAuthSignature.isBiometricChanged(_key);
    setState(() {
      _status = status?.toString();
    });
  }

  void _createKeyPair() async {
    try {
      final publicKey = await _localAuthSignature.createKeyPair(
        _key,
        AndroidPromptInfo(
          title: 'BIOMETRIC',
          subtitle: 'Please allow biometric',
          negativeButton: 'CANCEL',
          invalidatedByBiometricEnrollment: true,
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
      );
      await _localAuthSignature.resetBiometricChanged();
      setState(() {
        _publicKey = publicKey;
      });
      print('publicKey: $publicKey');
    } on PlatformException catch (e) {
      print('PlatformException: ${e.code}');
    }
  }

  void _sign() async {
    try {
      final signature = await _localAuthSignature.sign(
        _key,
        _payload,
        AndroidPromptInfo(
          title: 'BIOMETRIC',
          subtitle: 'Please allow biometric',
          negativeButton: 'CANCEL',
          invalidatedByBiometricEnrollment: true,
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
      );
      setState(() {
        _signature = signature;
      });
      print('signature: $signature');
    } on PlatformException catch (e) {
      print('PlatformException: ${e.code}');
    }
  }

  void _verify() async {
    try {
      final verified = await _localAuthSignature.verify(
        _key,
        _payload,
        _signature!,
        AndroidPromptInfo(
          title: 'BIOMETRIC',
          subtitle: 'Please allow biometric',
          negativeButton: 'CANCEL',
          invalidatedByBiometricEnrollment: true,
        ),
        IOSPromptInfo(reason: 'Please allow biometric'),
      );
      setState(() {
        _verified = '$verified';
      });
      print('verified: $verified');
    } on PlatformException catch (e) {
      print('PlatformException: ${e.code}');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: SingleChildScrollView(
          child: Container(
            margin: const EdgeInsets.all(16),
            child: Column(
              children: [
                const Text('PublicKey'),
                const SizedBox(height: 16),
                CardBox(child: Text('$_publicKey')),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: _createKeyPair,
                  child: const Text('Create KeyPair'),
                ),
                const Text('Biometric Changed'),
                const SizedBox(height: 16),
                CardBox(child: Text('$_status')),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: _checkIsBiometricChanged,
                  child: const Text('Check Biometric Changed'),
                ),
                const SizedBox(height: 16),
                const Text('Signature'),
                const SizedBox(height: 16),
                CardBox(child: Text('$_signature')),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: _sign,
                  child: const Text('Sign'),
                ),
                const SizedBox(height: 16),
                const Text('Verify'),
                const SizedBox(height: 16),
                CardBox(child: Text('$_verified')),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: _verify,
                  child: const Text('Verify'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用local_auth_signature插件来实现本地身份验证签名的示例代码。这个插件允许用户在设备上使用指纹、面部识别或其他生物识别方式进行身份验证,并捕获签名。

首先,确保你已经在你的pubspec.yaml文件中添加了local_auth_signature依赖:

dependencies:
  flutter:
    sdk: flutter
  local_auth_signature: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter项目中实现签名功能。以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:local_auth_signature/local_auth_signature.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Local Auth Signature Example'),
        ),
        body: Center(
          child: SignatureScreen(),
        ),
      ),
    );
  }
}

class SignatureScreen extends StatefulWidget {
  @override
  _SignatureScreenState createState() => _SignatureScreenState();
}

class _SignatureScreenState extends State<SignatureScreen> {
  String? _message;
  Uint8List? _signatureData;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          _message ?? 'Please authenticate to sign',
          style: TextStyle(fontSize: 20),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () async {
            bool authenticated = await LocalAuthSignature.authenticateWithBiometrics(
              reason: 'Please authenticate to sign',
              cancelButtonText: 'Cancel',
              fallbackButtonText: 'Use PIN',
              useFallback: true,
              style: LocalAuthSignatureStyle(
                containerDecoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                ),
                indicatorColor: Colors.blue,
                cancelButtonTextStyle: TextStyle(color: Colors.red),
                fallbackButtonTextStyle: TextStyle(color: Colors.black),
              ),
              onAuthenticated: (signature) {
                setState(() {
                  _message = 'Authenticated successfully!';
                  _signatureData = signature;
                });
                // 你可以在这里将签名数据保存到服务器或本地存储
              },
              onCancelled: () {
                setState(() {
                  _message = 'Authentication cancelled!';
                });
              },
              onError: (error) {
                setState(() {
                  _message = 'Authentication error: $error';
                });
              },
            );

            if (!authenticated) {
              setState(() {
                _message = 'Authentication failed!';
              });
            }
          },
          child: Text('Authenticate and Sign'),
        ),
        if (_signatureData != null) {
          SizedBox(height: 20),
          Image.memory(_signatureData!),
        },
      ],
    );
  }
}

代码说明:

  1. 依赖添加:在pubspec.yaml文件中添加local_auth_signature依赖。
  2. UI布局:使用Column布局来组织文本、按钮和签名图像。
  3. 身份验证按钮:使用ElevatedButton来触发身份验证。
  4. 身份验证回调
    • onAuthenticated:当身份验证成功时,将签名数据保存到状态并显示签名图像。
    • onCancelled:当身份验证取消时,更新状态消息。
    • onError:当身份验证出错时,更新状态消息。

这个示例代码展示了如何使用local_auth_signature插件进行本地身份验证并捕获签名。你可以根据需求进一步修改和扩展此代码。

回到顶部