ㄷㅣㅆㅣ's Amusement
[iOS/Objective-c] Touch Id 사용하여 인증하기. (passcode도 동작) 본문
[iOS/Objective-c] Touch Id 사용하여 인증하기. (passcode도 동작)
반응형
오늘은... iOS에서 지문인식을 통한 인증방법에대해 포스팅을 해봅니다.
우선... 지문인식 다이얼로그는 LAContext로 띄울 수 있는데.... 이것을 쓰면 "enter passcode"를 눌렀을 때 "User fallback"에러메시지가 떨어진 후 passcode입력할 수 있는 방법이 없기 때문에.. 나는 이를 우회할 수 있는 다른 방법을 쓰기로 한다.
1. flow
1) 키체인을 설정하되, 읽을 때 touch id(지문인식)을 요구하도록 설정한다.
2) 키체인을 읽어들이는 쿼리(query)를 실행한다.
1) keychain 설정.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | - (void)setKeychainForTouchIdVerify { LAContext *context = [[LAContext alloc] init]; NSError *error = nil; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error] == NO) { NSLog(@"This device don't support touch id verification."); return; } // LAContext만으로 TouchId verify를 할 수는 있으나, 실패시 passcode넣는 동선이 동작하지 않음. // 따라서 키체인을 이용하여 모두 지원할 수 있도록 workaround한다. // TODO : 키체인 설정. 이 부분은 한번만 실행되면 되기 때문에.. 추후 프로젝트 골격이 완성되면 적당한 곳으로 옮겨야 한다. // 패스워드 컨텐트는 어떤 문자든지 중요하지 않으나 꼭 넣어야 함. (애플 기본사항) NSData * pwData = [@"the password itself does not matter" dataUsingEncoding:NSUTF8StringEncoding]; // 키체인 엔트리가 읽히면 touch id나 passcode를 요구하도록 만든다. // 사용자가 passcode를 지웠을 때 키체인도 날리는 옵션을 제공하지만, 사용하는 동선이 없을 것으로 판단됨. 필요시 추후 개발 CFErrorRef accessControlError = NULL; SecAccessControlRef accessControlRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecAccessControlUserPresence, &accessControlError); if (accessControlRef == NULL || accessControlError != NULL) { NSLog(@"Cannot create SecAccessControlRef to store a password with identifier “%@” in the key chain: %@.", keychainItemIdentifier, accessControlError); return; } // Create the keychain entry attributes. identifier와 서비스 네임으로 유니크한 키체인 엔트리를 만듬. NSDictionary *attributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: (__bridge id)(kSecClassGenericPassword), kSecClass, keychainItemIdentifier, kSecAttrAccount, keychainItemServiceName, kSecAttrService, (__bridge id)accessControlRef, (__bridge id)kSecAttrAccessControl, @YES, (__bridge id)kSecUseNoAuthenticationUI, pwData, (__bridge id)kSecValueData, nil]; CFTypeRef result; OSStatus osStatus = SecItemAdd((__bridge CFDictionaryRef)attributes, &result); if (osStatus != noErr) { NSError * error = [[NSError alloc] initWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil]; NSLog(@"Adding generic password with identifier “%@” to keychain failed with OSError %d: %@.", keychainItemIdentifier, (int)osStatus, error); } } | cs |
2) query 실행
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | - (void)touchIdVerify:(void (^)(BOOL bVerified))verified { LAContext *context = [[LAContext alloc] init]; NSError *error = nil; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error] == NO) { NSLog(@"This device don't support touch id verification."); return; } // touch id scan UI가 뜨도록 하는부분. // touch id scan할 때 타이틀 NSString * secUseOperationPrompt = @"Authenticate for server login"; // 키체인관련 기능은 global_queue에서 해야한다. (다른 큐에서는 동작 안함) dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { NSMutableDictionary * query = [[NSMutableDictionary alloc] initWithObjectsAndKeys: (__bridge id)(kSecClassGenericPassword), kSecClass, keychainItemIdentifier, kSecAttrAccount, keychainItemServiceName, kSecAttrService, secUseOperationPrompt, kSecUseOperationPrompt, nil]; // 쿼리를 실행해서 touch id scan 시작 CFTypeRef result = nil; OSStatus userPresenceStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); if (userPresenceStatus == noErr) { NSLog(@"Fingerprint or device passcode validated."); verified(YES); } else { NSLog(@"Fingerprint or device passcode could not be validated. Status %d.", (int) userPresenceStatus); verified(NO); } }); } | cs |
3) 마무리.
- 지금까지 GUI에 관련된 그 어떤 작업도 하지 않았으나, 기본 지문인식 다이얼로그로 매우 원활히 인증이 가능하다.
이와 관련된 GUI는 할 필요가 없을 듯.... 물론 까탈스러운 UX디자이너가 요구해올 수 있겠지만... GUI의 수준이 기본 다이얼로그보다 좋지 않을것임이 뻔하다.
반응형
'Programming > iOS' 카테고리의 다른 글
[iOS/Objective-C] AES/CBC/NoPadding using CCCRypt (0) | 2015.12.16 |
---|---|
[iOS/Objective-c] UIButton background color 설정하기. (6) | 2015.11.30 |
[iOS/Objective-c]NSArray vs NSMutableArray 잘 사용하고 계신가요? (0) | 2015.11.19 |
iOS/Objective-c, code block 내에서 self 다루기 (2) | 2015.11.19 |
iOS calendar program tutorial (0) | 2015.11.10 |
Comments