我们能否在手机上注册生物指纹?我在Google上进行了搜索,发现了loca_auth flutter插件,但它只能获取生物特征指纹列表并验证指纹,但是我需要在设备中注册生物特征指纹。
答案 0 :(得分:0)
您可以执行此操作。看看这个: Fingerprint Authentication in Flutter
因此,您还需要在android清单文件中设置权限。
答案 1 :(得分:0)
无论您使用的是哪种平台(抖动等),第三方应用程序都无法将生物识别材料注册/添加到设备中。这是流程的总体运行方式。
现在在您的应用程序内部,当用户单击到authenticate()
时,您的应用程序实际上从未看到过任何生物识别材料。生物特征识别材料保存在安全的位置,以便第三方应用程序无法访问它们。您的应用程序从框架中获得的信息是,尝试向您的应用程序进行身份验证的指纹/面部/虹膜确实已在设备上注册。查看我提到的博客文章以获取更多详细信息。
答案 2 :(得分:0)
这是我们的应用程序中指纹认证的代码和完整的例子
首先创建一个 FingerprintAuthentication
类
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:lottie/lottie.dart';
import 'package:nb_utils/nb_utils.dart';
import 'package:prokit_flutter/main.dart';
import 'package:prokit_flutter/main/utils/AppColors.dart';
import 'package:prokit_flutter/main/utils/AppWidget.dart';
class FingerprintAuthentication extends StatefulWidget {
static String tag = '/FingerprintAuthentication';
@override
_FingerprintAuthenticationState createState() => _FingerprintAuthenticationState();
}
class _FingerprintAuthenticationState extends State<FingerprintAuthentication> {
final LocalAuthentication auth = LocalAuthentication();
bool face = false;
bool fingerprint = false;
String _authorized = 'Not Authorized';
bool _isAuthenticating = false;
bool authorized = false;
@override
void initState() {
super.initState();
init();
}
init() async {
await _getAvailableBiometrics();
}
@override
void setState(fn) {
if (mounted) super.setState(fn);
}
Future<void> _getAvailableBiometrics() async {
List<BiometricType> availableBiometrics = await auth.getAvailableBiometrics();
try {
face = availableBiometrics.contains(BiometricType.face);
fingerprint = availableBiometrics.contains(BiometricType.fingerprint);
setState(() {});
} on PlatformException catch (e) {
print(e);
}
}
Future<void> _authenticate() async {
bool authenticated = false;
try {
setState(() {
_isAuthenticating = true;
_authorized = 'Authenticating';
});
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to Login',
useErrorDialogs: true,
stickyAuth: true,
iOSAuthStrings: IOSAuthMessages(
cancelButton: 'cancel',
goToSettingsButton: 'settings',
goToSettingsDescription: 'Please set up your Touch ID.',
lockOut: 'Please reenable your Touch ID',
),
androidAuthStrings: AndroidAuthMessages(
signInTitle: "Fingerprint Authentication",
fingerprintRequiredTitle: "Connect to Login",
cancelButton: 'Cancel',
goToSettingsButton: 'Setting',
goToSettingsDescription: 'Please set up your Touch ID.',
fingerprintSuccess: "Authentication Successfully authenticated"),
);
authorized = authenticated;
setState(() {
_isAuthenticating = false;
_authorized = 'Authenticating';
});
} on PlatformException catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return HandleError(
code: e.code,
message: e.message,
);
});
}
if (!mounted) return;
final String message = authenticated ? 'Authorized' : 'Not Authorized';
setState(() {
authorized = authenticated;
_authorized = message;
});
await Future.delayed(Duration(seconds: 3));
setState(() {
authorized = authenticated;
});
}
void _cancelAuthentication() {
auth.stopAuthentication();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: appBar(context, 'Fingerprint Authentication'),
body: ListView(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(16),
scrollDirection: Axis.vertical,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
fingerprint
? InkWell(
borderRadius: BorderRadius.circular(10),
onTap: _isAuthenticating ? _cancelAuthentication : _authenticate,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: appColorPrimary),
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.fingerprint,
color: appColorPrimary,
size: 75,
),
10.height,
Text(
'Fingerprint',
style: boldTextStyle(
color: appColorPrimary,
),
)
],
),
),
)
: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () {
toast("Fingerprint not available");
},
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Icon(
Icons.fingerprint,
color: Colors.grey,
size: 75,
),
10.height,
Text(
'Fingerprint',
style: boldTextStyle(
color: Colors.grey,
),
)
],
),
),
),
face
? InkWell(
borderRadius: BorderRadius.circular(10),
onTap: _isAuthenticating ? _cancelAuthentication : _authenticate,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: appColorPrimary,
),
),
child: Column(
children: [
Icon(Icons.face, color: appColorPrimary, size: 75),
10.height,
Text(
'Face',
style: boldTextStyle(
color: appColorPrimary,
),
)
],
),
),
)
: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () {
toast("Face biometric is unavailable");
},
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey,
),
),
child: Column(
children: [
Icon(Icons.face, color: Colors.grey, size: 75),
10.height,
Text(
'Face',
style: boldTextStyle(
color: Colors.grey,
),
)
],
),
),
),
],
),
authorized
? Lottie.asset(
'images/integrations/img/authentication.json',
height: 250,
width: 250,
reverse: true,
animate: mounted,
repeat: false,
)
: SizedBox(),
],
),
),
);
}
}
创建一个 HandleError
类
class HandleError extends StatelessWidget {
final String code;
final String message;
HandleError({this.code, this.message});
@override
Widget build(BuildContext context) {
return Dialog(
child: Container(
decoration: BoxDecoration(
color: appStore.scaffoldBackground,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(0),
),
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
padding: EdgeInsets.all(8),
color: appColorPrimary,
child: Column(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
size: 75,
),
Text(code.validate(), textAlign: TextAlign.center, style: boldTextStyle(size: 18, color: white)),
],
),
),
Text(
message.validate(),
style: secondaryTextStyle(),
textAlign: TextAlign.justify,
).paddingOnly(left: 8, right: 8),
16.height,
FlatButton(
onPressed: () {
finish(context);
},
child: MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: Colors.red,
onPressed: () {
finish(context);
},
child: (Text(
'Retry',
style: boldTextStyle(color: Colors.white),
)),
),
),
16.height,
],
),
),
);
}
}