TouchID激活activateTouchWithResponse函数在未请求指纹的情况下返回成功。

20

我有以下的本地认证实现,正如许多地方所描述的。

context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
        dispatch_async(dispatch_get_main_queue(), {

        if success {
            let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        if let error = error {
            var message :String

            switch(error.code) {
            case LAError..AuthenticationFailed:
                message = "There was a problem verifying your identity."
            case LAError..UserCancel:
                message = "You pressed cancel."
            case LAError..UserFallback:
                message = "You pressed password."
            default:
                message = "Touch ID may not be configured"
            }

            let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
            self.presentViewController(alert, animated: true, completion: nil)
        }
    })
})

但是在我使用指纹成功进行身份验证后,然后调用 evaluatePolicy(,localizedReason:,reply:) 函数会直接返回成功而不要求任何指纹验证。

我实际上是通过 UISwitch 启用或禁用 TouchID,所以在禁用和重新启用后,我想重新进行身份验证并再次输入我的指纹。

为什么它会缓存认证?

谢谢


将错误作为 else if 添加,看看会发生什么。 - Konsy
错误为零。第二次评估策略时,我成功了,错误为零,而不需要提示触摸按钮。 - Cristian Pena
尝试使用 if error != nil 的方式进行操作。 - Konsy
3个回答

35

一旦评估了LAContext,它将返回成功,直到它被解除分配。您可以手动使其失效,然后返回的错误将是LAError.InvalidContext。

如果您每次都希望收到TouchID确认提示,则需要每次创建LAContext。这可以通过以下方式实现

context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
        dispatch_async(dispatch_get_main_queue(), {

        if success {
            let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        if let error = error {
            var message :String

            switch(error.code) {
            case LAError..AuthenticationFailed:
                message = "There was a problem verifying your identity."
            case LAError..UserCancel:
                message = "You pressed cancel."
            case LAError..UserFallback:
                message = "You pressed password."
            default:
                message = "Touch ID may not be configured"
            }

            let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        context = LAContext()
    })
})

很棒的答案,它澄清了情况,谢谢。在苹果文档中没有任何关于它的字眼,而短语:“不要假设以前成功的策略评估意味着未来的评估也会成功。策略评估可能因各种原因失败,包括用户或系统取消。”真的很令人困惑。 - Dren
使用 touchIDAuthenticationAllowableReuseDuration 是解决这个问题的预期(也更好的)解决方案。 - Matjan

9

自iOS 9以来,上下文中存在touchIDAuthenticationAllowableReuseDuration

Touch ID身份验证允许重用的持续时间。 如果在指定的时间间隔内成功使用Touch ID对设备进行了身份验证,则接收者的身份验证会自动成功,而无需提示用户使用Touch ID。 默认值为0,这意味着无法重复使用Touch ID身份验证。 Touch ID身份验证最长允许重用的持续时间由LATouchIDAuthenticationMaximumAllowableReuseDuration常量指定。您不能通过将此属性设置为大于此常量的值来指定更长的持续时间。 可用性 iOS(9.0及更高版本),macOS(10.12及更高版本)

例如,如果您将其设置为60

context.touchIDAuthenticationAllowableReuseDuration = 60

如果用户在过去60秒内成功通过了Touch ID的检查,它将自动成功通过而无需再次检查。

因此,您可以将其设置为适合您的值。我认为这很好,而且要求用户再次触摸屏幕(例如解锁屏幕)而他只是在几秒钟前才做了这件事,这很烦人。


请注意,从iOS 13.2 SDK开始,文档中写道:“如果在此时间间隔内通过生物识别成功解锁设备,(...)”。 - Olivier

2
我曾经遇到过同样的问题,但是我将持续时间值增加了如下所示:
context.touchIDAuthenticationAllowableReuseDuration = Double(5 * 60) // 5 min, 

这个解决方案对我来说有效。


你可以使用常量 LATouchIDAuthenticationMaximumAllowableReuseDuration,因为它是最大允许的时间间隔。它的值仅为5分钟。 - Ansari Awais

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接