循环世博会生物认证,直到成功

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;
                }
            }