循环世博会生物认证,直到成功
Loop expo biometric authentication until success
我正在尝试使用 React-native 和 Expo 在 Android 上实施生物认证(面部 ID / 指纹)。
使用 LocalAuthentication.authenticateAsync()
函数,用户可以使用他的生物特征进行身份验证。但如果失败,用户必须再次按下生物识别认证。
所以我尝试了一些递归或 while 循环的小技巧,但结果很奇怪:
const scanFingerPrint = async () => {
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
} catch (e) {
console.log(e);
}
};
使用此代码,如果用户未通过生物认证,它将无限地传入 "else"...
所以我想知道如何在 android 上处理它。
您可以使用变量手动处理它。
首先在构造函数中创建变量 retryCount
或作为 class 的 属性,以便在每个函数中都可以访问它。
constructor(props) {
super(props);
this.retryCount = 3;
}
在调用scanFingerPrint
函数之前设置retryCount
的值。
this.retryCount = 3; //number of attempts you want to provide
现在像下面这样修改函数以防止无限循环:
const scanFingerPrint = async () => {
try {
if (this.retryCount <= 0){
//exceeded the number of attempts..try again after a minute
} else{
this.retryCount--;
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
}
} catch (e) {
console.log(e);
}
};
您可以为尝试传递函数变量。
看到这个,
const scanFingerPrint = async (remainingAttempts = 5) => { // you can change 5 as per your choice
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential().then(credentials =>
onScan(credentials)
);
} else {
ShakeAnimation(animatedValueModal);
if (remainingAttempts) {
remainingAttempts--;
scanFingerPrint(remainingAttempts);
} else {
alert("You have exceeded max scan limit.");
}
}
} catch (e) {
console.log(e);
}
};
并且您不需要更改任何其他内容。不是你第一次调用函数。
Expo 提供了关于本地身份验证结果的 "error" 密钥。为了不处理硬件错误,我使用了这个:
if (!results.success) {
switch (results.error) {
case "lockout":
setLocked(true);
break;
case "authentication_failed" || "too_fast":
ShakeAnimation(animatedValueModal);
await scanBiometric();
break;
case "user_cancel" :
break;
default:
ShakeAnimation(animatedValueModal);
break;
}
}
我正在尝试使用 React-native 和 Expo 在 Android 上实施生物认证(面部 ID / 指纹)。
使用 LocalAuthentication.authenticateAsync()
函数,用户可以使用他的生物特征进行身份验证。但如果失败,用户必须再次按下生物识别认证。
所以我尝试了一些递归或 while 循环的小技巧,但结果很奇怪:
const scanFingerPrint = async () => {
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
} catch (e) {
console.log(e);
}
};
使用此代码,如果用户未通过生物认证,它将无限地传入 "else"...
所以我想知道如何在 android 上处理它。
您可以使用变量手动处理它。
首先在构造函数中创建变量 retryCount
或作为 class 的 属性,以便在每个函数中都可以访问它。
constructor(props) {
super(props);
this.retryCount = 3;
}
在调用scanFingerPrint
函数之前设置retryCount
的值。
this.retryCount = 3; //number of attempts you want to provide
现在像下面这样修改函数以防止无限循环:
const scanFingerPrint = async () => {
try {
if (this.retryCount <= 0){
//exceeded the number of attempts..try again after a minute
} else{
this.retryCount--;
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
}
} catch (e) {
console.log(e);
}
};
您可以为尝试传递函数变量。
看到这个,
const scanFingerPrint = async (remainingAttempts = 5) => { // you can change 5 as per your choice
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential().then(credentials =>
onScan(credentials)
);
} else {
ShakeAnimation(animatedValueModal);
if (remainingAttempts) {
remainingAttempts--;
scanFingerPrint(remainingAttempts);
} else {
alert("You have exceeded max scan limit.");
}
}
} catch (e) {
console.log(e);
}
};
并且您不需要更改任何其他内容。不是你第一次调用函数。
Expo 提供了关于本地身份验证结果的 "error" 密钥。为了不处理硬件错误,我使用了这个:
if (!results.success) {
switch (results.error) {
case "lockout":
setLocked(true);
break;
case "authentication_failed" || "too_fast":
ShakeAnimation(animatedValueModal);
await scanBiometric();
break;
case "user_cancel" :
break;
default:
ShakeAnimation(animatedValueModal);
break;
}
}