LocalAuthentication开发实践

本文详细介绍了iOS中LocalAuthentication框架的使用,包括基础用法、最佳实践,特别是针对iOS 9及以上版本的Face ID验证过程。还讨论了如何控制Keychain访问权限、复用设备解锁授权和更灵活的访问控制策略。通过对LocalAuthentication的深入理解,开发者可以更好地实现生物识别安全功能。
摘要由CSDN通过智能技术生成

在iPhone 5s加入Touch ID后,指纹识别的功能在App中逐渐受到青睐,特别是对于本地安全较高的应用(如带支付的App)指纹识别是必备的功能,它既能解决在验证过程中输入密码的繁琐过程,同时指纹识的安全等级更高。那么,要想在自己开发的应用中使用指纹识别,就必须要LocalAuthentication.framework提供的API,下面将详细地介绍如何使用这个框架来实现指纹识别功能。

基础用法

我们先来看下面的例子:

LAContext *context = [[LAContext alloc] init];
    
NSError *error = nil;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error])
{
   
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"输入指纹进行验证" reply:^(BOOL success, NSError * _Nullable error) {
   
            
        if (success)
        {
   
            NSLog(@"验证成功");
        }
        else
        {
   
            NSLog(@"验证失败");
        }

    }];
}
else
{
   
    NSLog(@"识别功能不可用");
}

我们来解读一下上面的代码:

  • LAContext为贯穿整个识别过程的对象类型。使用识别必须初始化一个LAContext对象。

  • 在进行指纹(人脸)识别前,需要判断识别功能是否可用,上面代码中的canEvaluatePolicy: error :方法就是做这样一件事情。当方法返回YES时则可以继续调用识别方法。否则需要根据error的描述来提示用户。该方法的policy参数决定了鉴权的行为方式,该参数取值如下:

取值 说明
LAPolicyDeviceOwnerAuthenticationWithBiometrics 指纹(人脸)识别。验证弹框有两个按钮,第一个是取消按钮,第二个按钮可以自定义标题名称(输入密码)。只有在第一次指纹验证失败后才会出现第二个按钮,这种方式下的第二个按钮功能需要自己定义。前三次指纹验证失败,指纹验证框不再弹出。再次重新进入验证,还有两次验证机会,如果还是验证失败,TOUCH ID 被锁住不再继续弹出指纹验证框。以后的每次验证都将会弹出设备密码输入框直至输入正确的设备密码才能重新使用指纹(人脸)识别
LAPolicyDeviceOwnerAuthentication 指纹(人脸)识别或系统密码验证。如果Touch ID (Face ID)可用,且已经录入指纹(人脸),则优先调用指纹(人脸)验证。其次是调用系统密码验证,如果没有开启设备密码,则不可以使用这种验证方式。指纹(人脸)识别验证失败三次将弹出设备密码输入框,如果不进行密码输入。再次进来还可以有两次机会验证指纹(人脸),如果都失败则Touch ID(Face ID)被锁住,以后每次进来验证都是调用系统的设备密码直至输入正确的设备密码才能重新使用指纹(人脸)识别

该方法可以能返回的错码如下所示:

错误码 说明
LAErrorPasscodeNotSet 没有设置设备密码,无法使用指纹(人脸)识别
LAErrorTouchIDNotAvailable 设备不支持Touch ID/Face ID,iOS 11被标注过时,需要使用LAErrorBiometryNotAvailable代替
LAErrorBiometryNotAvailable 设备不支持Touch ID/Face ID,iOS 11新增,由于新增Face ID,故用来代替LAErrorTouchIDNotAvailable
LAErrorTouchIDNotEnrolled 没有录入指纹/人脸,iOS 11被标注过时,需要使用LAErrorBiometryNotEnrolled代替
LAErrorBiometryNotEnrolled 没有录入指纹/人脸,iOS 11新增,由于新增Face ID,故用来代替LAErrorTouchIDNotEnrolled
LAErrorBiometryLockout 超过重试限制,Touch ID/Face ID被锁定,需要进行设备密码解锁后重新激活
  • 检测可用后,调用evaluatePolicy:localizedReason:reply:方法来进行指纹(人脸)识别。其中policy参数应该与调用canEvaluatePolicy: error :方法时传入的policy一致。而localizedReason则是显示在识别标题下面的一栏描述文本,如图所示:

localizedReason显示位置

该方法返回的错误如下所示:

错误码 说明
LAErrorPasscodeNotSet 没有设置设备密码,无法使用指纹(人脸)识别
LAErrorTouchIDNotAvailable 设备不支持Touch ID/Face ID,iOS 11被标注过时,需要使用LAErrorBiometryNotAvailable代替
LAErrorBiometryNotAvailable 设备不支持Touch ID/Face ID,iOS 11新增,由于新增Face ID,故用来代替LAErrorTouchIDNotAvailable
LAErrorTouchIDNotEnrolled 没有录入指纹/人脸,iOS 11被标注过时,需要使用LAErrorBiometryNotEnrolled代替
LAErrorBiometryNotEnrolled 没有录入指纹/人脸,iOS 11新增,由于新增Face ID,故用来代替LAErrorTouchIDNotEnrolled
LAErrorBiometryLockout 超过重试限制,Touch ID/Face ID被锁定,需要进行设备密码解锁后重新激活
LAErrorAuthenticationFailed 验证失败,指的是指纹(人脸)不匹配
LAErrorUserCancel 用户点击了取消按钮
LAErrorUserFallback 用户点击了输入密码按钮
LAErrorSystemCancel 系统强制取消,可能由于其他应用进入前台
LAErrorAppCancel 应用调用了LAContextinvalidate方法
LAErrorNotInteractive 应用尚未启动完成或者已经进入非激活状态时调用验证方法会收到该错误,例如:将验证方法放到didEnterBackground方法中进行可能会导致这个错误。

通过上面的例子和解释,大家对LocalAuthentication这个框架应该有了一定的了解吧,但是作为一种验证方式,上面的做法是不够安全和严谨的。举个例子,如果我知道你的设备密码,然后通过密码登录你的手机,然后我在你的设备上登记了我的指纹,那么按照上面代码的逻辑,我的指纹也是能够验证通过的。因此,这里需要借助iOS 9上LAContext的一个新属性evaluatedPolicyDomainState来解决这个问题(没听错,是iOS 9上新增的,也就是说在iOS 8上会存在我说的这种问题,可能苹果爸爸一开始考虑,既然手机设备密码都泄漏了,那么自然手机里面的信息都是不安全的,但是往往App中的验证体系是独立于系统的,某些重要的App密码不泄漏还是很安全的,但是加入了指纹识别后可能就变得不安全了,所以不建议iOS 8上实现指纹识别功能)。

evaluatedPolicyDomainState表示当下Touch ID/Face ID的一个状态,没有其他的含义。当在在设备上添加、删除指纹(人脸)时,这个值就会发生变化。所以,拿到这个值作比对就能够很容易知道是否有发生变化,下面将继续介绍具体的实现方法。

最佳实践(仅iOS 9及以上)

在写代码前,先来理清楚整个实现的过程,在一般的情况下我们都会给应用做一个开关,用于控制是否开启指纹识别。那么,基于这个前提,我们可以作如下的流程处理:

  1. 设置一个开关(UISwitch
  2. 当开关开启时,要求用户进行指纹识别,在识别成功后将evaluatedPolicyDomainState保存起来,用于后续指纹验证时对比。
  3. 在需要验证的地方,使用指纹识别API进行验证,同时获取evaluatedPolicyDomainState来比对之前保存的值,如果相同则验证成功,否则验证失败,需要进行后续的处理,如需要输入应用账号的密码。
  4. 通过App自身验证体系检测通过后在把新的evaluatedPolicyDomainState保存起来,用于往后的验证操作。

理解上面的流程后,我们来看下面的示例代码:

- (IBAction)switchChangedHandler:(id)sender
{
   
    if (self.touchIdSwitch.on)
    {
   
        //开启指纹
        LAContext *context = [[LAContext alloc] init];
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil])
        {
   
            //进行第一次的验证,成功后记录验证状态
            [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"输入指纹开启验证" reply:^(BOOL success, NSError * _Nullable error) {
   
                
                if (success)
                {
   
                    self.policyDomainState = context.evaluatedPolicyDomainState;
                }
                else
                {
   
                    NSLog(@"验证失败");
                    self.touchIdSwitch.on = NO;
                }
                
            }];
        }
        else
        {
   
            NSLog(@"Touch ID/Face ID不可用");
            self.touchIdSwitch.on = NO;
        }
    }
    else
    {
   
        self.policyDomainState = nil;
    }
}

- (IBAction)validationButtonClickedHandler:(id)sender
{
   
    if (self.touchIdSwitch.on)
    {
   
        LAContext *context = [[LAContext alloc] init];
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil])
        {
   
            //进行第一次的验证,成功后记录验证状态
            [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"使用指纹识别验证" reply:^(BOOL success, NSError * _Nullable error) {
   
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值