iOS 生物識別 Touch ID&FaceID

簡介

Touch ID是蘋果公司的一種指紋識別技術(shù),從iPhone 5s開始憔恳,早已為人們所熟知摔刁。

Touch ID不存儲用戶的任何指紋圖像挥转,只保存代表指紋的數(shù)字字符。蘋果公司提供Touch ID給第三方應(yīng)用程序使用共屈,程序只會收到認(rèn)證是否成功的通知绑谣,而無法訪問 Touch ID 或與已注冊指紋相關(guān)的數(shù)據(jù),這一點對安全而言尤為重要拗引。

現(xiàn)在有很多銀行類APP借宵、涉及到支付類的APP都集成了指紋、手勢等二次驗證功能矾削,從而使APP獲得更高的安全性壤玫。今天我們就來分析一下指紋識別登錄功能的具體實現(xiàn)。

實現(xiàn)步驟

1.首先引入指紋解鎖的庫文件

#import <LocalAuthentication/LocalAuthentication.h>

2.兩個主要方法

///這個方法是判斷設(shè)備是否支持TouchID的
- (BOOL)canEvaluatePolicy:(LAPolicy)policy error:(NSError * __autoreleasing *)error __attribute__((swift_error(none)))
    API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0));
///這個是用來驗證TouchID的哼凯,會有彈出框出來
- (void)evaluatePolicy:(LAPolicy)policy
       localizedReason:(NSString *)localizedReason
                 reply:(void(^)(BOOL success, NSError * __nullable error))reply
    API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0));

3.核心源碼

- (void)touchID {
    
    //創(chuàng)建LAContext
    LAContext *context = [LAContext new];
    
    //這個屬性是設(shè)置指紋輸入失敗之后的彈出框的選項
    context.localizedFallbackTitle = @"沒有忘記密碼";
    
    ///錯誤信息
    NSError *error = nil;
    ///這個方法是判斷設(shè)備是否支持TouchID的
    BOOL isUseTouchID = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
    if (isUseTouchID) {
        NSLog(@"支持指紋識別");
        //這個是用來驗證TouchID的垦细,會有彈出框出來
        [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"請按home鍵指紋登錄" reply:^(BOOL success, NSError * _Nullable error) {
            if (success) {
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@"驗證成功");
                });
                
            }else{
                NSLog(@"%@",error.localizedDescription);
                switch (error.code) {
                    case LAErrorSystemCancel:
                    {
                        NSLog(@"系統(tǒng)取消授權(quán),如其他APP切入");
                        break;
                    }
                    case LAErrorUserCancel:
                    {
                        NSLog(@"用戶取消驗證Touch ID");
                        break;
                    }
                    case LAErrorAuthenticationFailed:
                    {
                        NSLog(@"授權(quán)失敗");
                        break;
                    }
                    case LAErrorPasscodeNotSet:
                    {
                        NSLog(@"系統(tǒng)未設(shè)置密碼");
                        break;
                    }
                    case LAErrorBiometryNotAvailable:
                    {
                        NSLog(@"設(shè)備Touch ID不可用挡逼,例如未打開");
                        break;
                    }
                    case LAErrorBiometryNotEnrolled:
                    {
                        NSLog(@"設(shè)備Touch ID不可用括改,用戶未錄入");
                        break;
                    }
                    case LAErrorUserFallback:
                    {
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                            NSLog(@"用戶選擇輸入密碼,切換主線程處理");
                        }];
                        break;
                    }
                    default:
                    {
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                            NSLog(@"其他情況,切換主線程處理");
                        }];
                        break;
                    }
                }
            }
        }];
    }else{
        NSLog(@"不支持指紋識別");
        switch (error.code) {
            case LAErrorBiometryNotEnrolled:
            {
                NSLog(@"TouchID is not enrolled TouchID未注冊");
                break;
            }
            case LAErrorPasscodeNotSet:
            {
                NSLog(@"A passcode has not been set 未設(shè)置密碼");
                break;
            }
            default:
            {
                NSLog(@"TouchID not available TouchID不可用");
                break;
            }
        }
        
        NSLog(@"%@",error.localizedDescription);
    }
    
}

原文鏈接:iOS 指紋識別登錄功能實現(xiàn)

============

項目中的優(yōu)化

實際項目中這個業(yè)務(wù)實現(xiàn)的難點在于嘱能,首次登錄成功并啟用指紋授權(quán)--->退出APP后--->二次啟動APP吝梅,如何判斷是否要啟用指紋登錄驗證呢?這時就需要我們對數(shù)據(jù)持久化和數(shù)據(jù)共享有較深的理解惹骂,很多APP開發(fā)者苏携,在開發(fā)登錄保持的時候,大都會使用持久化數(shù)據(jù)的方式对粪,存儲成功登錄的標(biāo)記右冻。但對于安全性較高的APP,每次重新啟動時都會校驗登錄狀態(tài)著拭,單靠持久化數(shù)據(jù)是不夠的纱扭。

我的解決方案是:
通過三個數(shù)據(jù)進行登錄保持

loginState:持久化數(shù)據(jù),用于存儲用戶登錄成功儡遮,未激活狀態(tài)乳蛾;
startAutoLoginState:持久化數(shù)據(jù),是否開啟指紋識別授權(quán)鄙币;
isAppCurrentLoginState:共享數(shù)據(jù)肃叶,登錄激活狀態(tài),該狀態(tài)的特點十嘿,每次重新啟動APP都會重新初始化數(shù)據(jù)因惭。


原文鏈接:iOS指紋識別登錄流程及實現(xiàn)

typedef NS_ENUM(NSInteger, LAError)
{
    //身份驗證不成功,因為用戶無法提供有效的憑據(jù)绩衷。
    LAErrorAuthenticationFailed = kLAErrorAuthenticationFailed,

    //認(rèn)證被用戶取消(例如了取消按鈕)筛欢。
    LAErrorUserCancel = kLAErrorUserCancel,

    //認(rèn)證被取消了,因為用戶利用回退按鈕(輸入密碼)。
    LAErrorUserFallback = kLAErrorUserFallback,

    //身份驗證被系統(tǒng)取消了(如另一個應(yīng)用程序去前臺)唇聘。
    LAErrorSystemCancel = kLAErrorSystemCancel,

    //身份驗證無法啟動,因為設(shè)備沒有設(shè)置密碼版姑。
    LAErrorPasscodeNotSet = kLAErrorPasscodeNotSet,

    //身份驗證無法啟動,因為觸摸ID不可用在設(shè)備上。
    LAErrorTouchIDNotAvailable NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotAvailable") = kLAErrorTouchIDNotAvailable,

    //身份驗證無法啟動,因為沒有登記的手指觸摸ID迟郎。
    LAErrorTouchIDNotEnrolled NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotEnrolled") = kLAErrorTouchIDNotEnrolled,

    //驗證不成功,因為有太多的失敗的觸摸ID嘗試和觸///摸現(xiàn)在ID是鎖著的剥险。
    //解鎖TouchID必須要使用密碼,例如調(diào)用LAPolicyDeviceOwnerAuthenti//cationWithBiometrics的時候密碼是必要條件宪肖。
    //身份驗證不成功表制,因為有太多失敗的觸摸ID嘗試和觸摸ID現(xiàn)在被鎖定。
    LAErrorTouchIDLockout NS_ENUM_DEPRECATED(10_11, 10_13, 9_0, 11_0, "use LAErrorBiometryLockout")
    __WATCHOS_DEPRECATED(3.0, 4.0, "use LAErrorBiometryLockout") __TVOS_DEPRECATED(10.0, 11.0, "use LAErrorBiometryLockout") = kLAErrorTouchIDLockout,

    //應(yīng)用程序取消了身份驗證(例如在進行身份驗證時調(diào)用了無效)控乾。
    LAErrorAppCancel NS_ENUM_AVAILABLE(10_11, 9_0) = kLAErrorAppCancel,

    //LAContext傳遞給這個調(diào)用之前已經(jīng)失效么介。
    LAErrorInvalidContext NS_ENUM_AVAILABLE(10_11, 9_0) = kLAErrorInvalidContext,

    //身份驗證無法啟動,因為生物識別驗證在當(dāng)前這個設(shè)備上不可用。
    LAErrorBiometryNotAvailable NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotAvailable,

    //身份驗證無法啟動蜕衡,因為生物識別沒有錄入信息壤短。
    LAErrorBiometryNotEnrolled NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotEnrolled,

    //身份驗證不成功,因為太多次的驗證失敗并且生物識別驗證是鎖定狀態(tài)。此時久脯,必須輸入密碼才能解鎖纳胧。例如LAPolicyDeviceOwnerAuthenticationWithBiometrics時候?qū)⒚艽a作為先決條件。
    LAErrorBiometryLockout NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryLockout,

    //身份驗證失敗帘撰。因為這需要顯示UI已禁止使用interactionNotAllowed屬性跑慕。  據(jù)說是beta版本
    LAErrorNotInteractive API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0)) = kLAErrorNotInteractive,
} NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0);


FaceID

注意要添加權(quán)限

Privacy - Face ID Usage Description

1.首先引入指紋解鎖的庫文件

#import <LocalAuthentication/LocalAuthentication.h>

2.核心源碼

-(void)faceID{
        NSError *error;
        
        LAContext *context = [[LAContext alloc]init];
        
        BOOL canAuthentication = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];
        if (canAuthentication) {
            
            [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"FaceID驗證" reply:^(BOOL success, NSError * _Nullable error) {
                //注意iOS 11.3之后需要配置Info.plist權(quán)限才可以通過Face ID驗證哦!不然只能輸密碼啦...
                if (success) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        NSLog(@"驗證成功");
                    });
                } else {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        NSLog(@"當(dāng)前軟件被掛起并取消了授權(quán) (如App進入了后臺等)");
                        NSLog(@"error-->%@",error);
                    });
                    
                }
            }];
        }
}

========
判斷設(shè)備是否支持TouchID 和 FaceID

-(void)justTouchIDFaceID{
    
    // 檢測設(shè)備是否支持TouchID或者FaceID
        if (@available(iOS 8.0, *)) {
            LAContext *LAContent = [[LAContext alloc] init];

            NSError *authError = nil;
            BOOL isCanEvaluatePolicy = [LAContent canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError];

            if (authError) {
                NSLog(@"檢測設(shè)備是否支持TouchID或者FaceID失敗摧找!\n error : == %@",authError.localizedDescription);
            } else {
                if (isCanEvaluatePolicy) {
                    // 判斷設(shè)備支持TouchID還是FaceID
                    if (@available(iOS 11.0, *)) {
                        switch (LAContent.biometryType) {
                            case LABiometryTypeNone:
                            {
                                NSLog(@"The device does not support biometry.");
                            }
                                break;
                            case LABiometryTypeTouchID:
                            {
                                NSLog(@"The device supports Touch ID.");
                            }
                                break;
                            case LABiometryTypeFaceID:
                            {
                                NSLog(@"The device supports Face ID.");
                            }
                                break;
                            default:
                                break;
                        }
                    } else {
                        // Fallback on earlier versions
                        NSLog(@"iOS 11之前不需要判斷 biometryType");
                        // 因為iPhoneX起始系統(tǒng)版本都已經(jīng)是iOS11.0核行,所以iOS11.0系統(tǒng)版本下不需要再去判斷是否支持faceID,直接走支持TouchID邏輯即可蹬耘。
                        NSLog(@"The device supports Face ID.");
                    }

                } else {
                    NSLog(@"The device does not support biometry.");
                }
            }

        } else {
            // Fallback on earlier versions
            NSLog(@"The device does not support biometry.");
        }
    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芝雪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子婆赠,更是在濱河造成了極大的恐慌绵脯,老刑警劉巖佳励,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件休里,死亡現(xiàn)場離奇詭異,居然都是意外死亡赃承,警方通過查閱死者的電腦和手機妙黍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞧剖,“玉大人拭嫁,你說我怎么就攤上這事∽ビ冢” “怎么了做粤?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捉撮。 經(jīng)常有香客問我怕品,道長,這世上最難降的妖魔是什么巾遭? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任肉康,我火速辦了婚禮,結(jié)果婚禮上灼舍,老公的妹妹穿的比我還像新娘吼和。我一直安慰自己,他們只是感情好骑素,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布炫乓。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厢岂。 梳的紋絲不亂的頭發(fā)上光督,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音塔粒,去河邊找鬼结借。 笑死,一個胖子當(dāng)著我的面吹牛卒茬,可吹牛的內(nèi)容都是我干的船老。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼圃酵,長吁一口氣:“原來是場噩夢啊……” “哼柳畔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起郭赐,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤薪韩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捌锭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俘陷,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年观谦,在試婚紗的時候發(fā)現(xiàn)自己被綠了拉盾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡豁状,死狀恐怖捉偏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泻红,我是刑警寧澤夭禽,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站谊路,受9級特大地震影響讹躯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凶异,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一蜀撑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剩彬,春花似錦酷麦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽母廷。三九已至,卻和暖如春糊肤,著一層夾襖步出監(jiān)牢的瞬間琴昆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工馆揉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留业舍,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓升酣,卻偏偏與公主長得像舷暮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子噩茄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 由于自己的產(chǎn)品接下來可能要支持touch id下面,所以有必要對ios的指紋識別做一下預(yù)研。去年九月份绩聘,隨著 iPho...
    JonnyHoang閱讀 1,192評論 0 6
  • 簡介 Touch ID是蘋果公司的一種指紋識別技術(shù)沥割,從iPhone 5s開始,早已為人們所熟知凿菩。 Touch ID...
    Swift社區(qū)閱讀 2,382評論 0 4
  • 指紋登陸 隨著智能時代的來臨机杜,人們越來越習(xí)慣于將重要信息和個人隱私存放于智能手機中。這時手機數(shù)據(jù)的安全性就變得尤其...
    sz_藍天使者閱讀 2,438評論 0 0
  • 實用原理: 指紋識別技術(shù)就是把一個人同他的指紋對應(yīng)起來蓄髓,通過比較他的指紋和預(yù)先保存的指紋進行比較叉庐,就可以驗證他的真...
    艷曉閱讀 3,207評論 0 19
  • 簡介 iPhone 5s~iPhone 8都可以通過指紋進行解鎖舒帮,省去了反復(fù)輸入密碼的繁瑣程序会喝,這個就是Touch...
    JQWONG閱讀 714評論 0 4