Skip to content


조회 수 180 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

안녕하세요.

 

염치불구하고 부탁드려요~~~

 

생체인증(face ID)을 시도하는 함수를 호출할 때마다 생체인증 체크하는 화면을 띄우고, 그리고 기기에 등록된 유효한 얼굴인지 체크하게 하고 싶습니다.

현재 문제는 인증이 성공된 후 최소 하루 정도는 무조건 성공으로 처리 해 버립니다. 예를 들어 "인증완료" 라는 세션 같은것을 적용 해 버리는 듯 합니다.

어떻게 해야 할까요?

 

호출하는 순서는 아래와 같습니다.

1. 웹뷰의 login.php 에서 앱의 call_bioMetricAuth 메소드를 호출합니다.

2. 앱의 ViewController.swift 에서 아래의 메소드가 실행됩니다.

                    } else if action == "call_bioMetricAuth"

                                , let cmd = dictionary["cmd"]

                                , let site_code = dictionary["site_code"]

                                , let domain_url = dictionary["domain_url"]

                                , let userid_ori = dictionary["userid_ori"]

                                , let userid = dictionary["userid"]

                                , let login_date = dictionary["login_date"]

                                , let return_url = dictionary["return_url"] {   // biometric 20230105

                        print("called call_bioMetricAuth in ViewController")

                        bioMetricManager.bioMetricAuth(cmd_para: cmd, site_code_para: site_code, domain_url_para: domain_url, userid_ori_para: userid_ori, userid_para: userid, login_date_para: login_date, return_url_para: return_url) { resultCode, resultMsg, guideMsg, bioDictionary in

                            if (resultCode > 1) {

                                if (guideMsg != "") {

                                    self.showToast(message: guideMsg)

                                }

                                if (resultCode == 100 ) {   // resultMsg is 이동할 url

                                    self.setCookieToWeb(cook_name: "isRegisteredBioAuth", cook_value: "T", expires_date: "15")

                                    self.goto_url(url: resultMsg)

                                } else {

                                    if (resultMsg == "exec_setToggleBtnDiableToWeb") {

                                        self.setToggleBtnDiableToWeb()

                                    } else if (resultMsg == "isSuccessBioinfoDelete") {

                                        let sql = bioDictionary["sql_delete"]

                                        self.dbManagerMember.sql_query(sql: sql!)

                                        self.setCookieToWeb(cook_name: "isRegisteredBioAuth", cook_value: "", expires_date: "-1")

                                    } else if (resultMsg == "bioAuthFailed") {

                                        let cmd = bioDictionary["cmd"]

                                        if (cmd == "bioInfoRegister") {

                                            self.setToggleBtnDiableToWeb()

                                        }

                                    }

                                }

                            }

                        }

                    } // end of call_bioMetricAuth

3. 아래는 BioMetricMyManager.swift 입니다.

import Foundation

import LocalAuthentication

 

class BioMetricMyManager: NSObject {    // NSObject

    let dbManagerMember = DatabaseManagerMember.shared

    var tbl_member: String = ""

    var pkg_name: String?

    var command: String?

    var site_code: String?

    var domain_url: String?

    var userid_ori: String?

    var userid: String?

    var return_url: String = ""

    var login_date: String?

    var auto_login_url: String = "";    // 로그인 후 돌아갈 return_url 값도 이 변수에 저장한다.

    var isValidBioDevice: Bool = false;

    var errMsgBiometricAvailable: String = ""

    var dictForMain: [String: String] = [:]

    enum BiometricType {

        case none

        case touchID

        case faceID

        case unknown

    }

    enum BiometricError: LocalizedError {

        case authenticationFailed

        case userCancel

        case userFallback

        case biometryNotAvailable

        case biometryNotEnrolled

        case biometryLockout

        case unknown

        

        var errorDescription: String? {

            switch self {

            case .authenticationFailed: return "사용자의 신원을 확인하는 중 문제가 발생했습니다."    // There was a problem verifying your identity."

            case .userCancel: return "취소를 눌렀습니다."   // You pressed cancel."

            case .userFallback: return "인증을 취소하였습니다."   // You pressed password."

            case .biometryNotAvailable: return "하드웨어를 사용할 수 없기 때문에 사용자가 인증할 수 없습니다. 나중에 다시 시도하십시오." // Face ID/Touch ID is not available."

            case .biometryNotEnrolled: return "생체 인식 또는 장치 자격 증명이 등록되지 않았기 때문에 사용자가 인증할 수 없습니다."    // Face ID/Touch ID is not set up."

            case .biometryLockout: return "생체인증이 잠겨있습니다."   // Face ID/Touch ID is locked."

            case .unknown: return "생체인증이 구성되지 않을 수 있습니다."   // Face ID/Touch ID may not be configured"

            }

        }

    }

    

    private let context = LAContext()

    private let policy: LAPolicy

    private let localizedReason: String

    

    private var error: NSError?

    

    init(policy: LAPolicy = .deviceOwnerAuthenticationWithBiometrics,

         localizedReason: String = "다시 시도",

         localizedFallbackTitle: String = "인식되지 않음") {

        

        self.policy = policy

        self.localizedReason = localizedReason

        context.localizedFallbackTitle = "" // 공백을 넣어야 실패했을 때 암호입력하라는 문구가 나오지 않는다 localizedFallbackTitle

        context.localizedCancelTitle = "인증을 취소합니다."

        self.tbl_member = dbManagerMember.get_table_name()

    }

    

    func bioMetricInit() {

        self.isValidBioDevice = true

        self.errMsgBiometricAvailable = checkBiometricAvailable()   // edit_20221214

    }

    

    func checkBiometricAvailable() -> String {

        guard context.canEvaluatePolicy(policy, error: &error) else {

            //let type = biometricType(for: context.biometryType)

            //print("bio type: \(type)")

            guard let error = error else {

                //return completion(false, type, nil)

                return "생체인증을 사용할 수 없습니다."

            }

            let ErrCode = biometricError(from: error)

            return ErrCode.errorDescription ?? "생체인증을 사용할 수 없습니다.(1)"

        }

        return ""

    }

    func bioMetricAuth(cmd_para: String, site_code_para: String, domain_url_para: String, userid_ori_para: String, userid_para: String, login_date_para: String, return_url_para: String, onCompletion: @escaping (Int, String, String, [String: String]) -> Void) {

        if (isValidBioDevice) {

            print("isValidBioDevice is true")

        }

        var resultCode = 1

        var resultMsg = ""

        var guideMsg = ""

        if (errMsgBiometricAvailable != "") {   // 에러 발생

            var isViewErrMsg = true

            if (cmd_para == "bioInfoRegister") {

                onCompletion(resultCode, "exec_setToggleBtnDiableToWeb", guideMsg, dictForMain)

            } else if (cmd_para == "bioInfoDelete") {

                if (site_code_para != "") {

                    var sql = "delete from " + tbl_member

                    sql = sql + " where site_code='" + site_code_para + "' and data_type='biometric'"

                    dictForMain["sql_delete"] = sql

                    onCompletion(4, "isSuccessBioinfoDelete", "생체인증 정보가 삭제되었습니다.", dictForMain)

                }

            }

            if (isViewErrMsg) {

                onCompletion(3, "onlyViewToast", errMsgBiometricAvailable, dictForMain)

            }

        } else {

            print("cmd_para: " + cmd_para)

            command = cmd_para;

            site_code = site_code_para;

            domain_url = domain_url_para;

            userid_ori = userid_ori_para;

            userid = userid_para;

            login_date = login_date_para;

            return_url = return_url_para;

            if (cmd_para == "bioInfoRegister") {

                if (site_code_para == "") {

                    guideMsg = "먼저 로그인을 하신 후 등록해 주십시오.";

                    onCompletion(2, "exec_setToggleBtnDiableToWeb", guideMsg, dictForMain)

                } else {

                    self.evaluate { [weak self] (success, error) in

                        if success {

                            self!.bioInfoRegister()

                            guideMsg = "생체인증 등록이 완료되었습니다."

                            onCompletion(100, self!.return_url, guideMsg, self?.dictForMain ?? [:])

                        } else {

                            guideMsg = error?.localizedDescription ?? "Face ID/Touch ID may not be configured"

                            self?.dictForMain["cmd"] = cmd_para

                            onCompletion(3, "bioAuthFailed", guideMsg, self?.dictForMain ?? [:])

                        }

                    }

                }

            } else if (cmd_para == "bioInfoDelete") {

                if (site_code_para == "") {

                    onCompletion(3, "onlyViewToast", "사이트 정보가 없습니다.", dictForMain)

                } else {

                    var sql = "delete from " + tbl_member

                    sql = sql + " where site_code='" + site_code! + "' and data_type='biometric'"

                    dictForMain["sql_delete"] = sql

                    onCompletion(4, "isSuccessBioinfoDelete", "생체인증 정보가 삭제되었습니다.", dictForMain)

                }

            } else {    // loginFromBioInfo

                var isGotoNext = true

                let isChangedBioAuthInfo = false    // isChangedBiometric(); // 인증정보가 바뀌었는지에 대한 flag => true: 바뀌었음

                if (isChangedBioAuthInfo) {

 

                }

                if (isGotoNext) {

                    let is_exist = bioInfoCheckFromTable();

                    if (is_exist) {

                        // 로그인 시도 시켜라

                        self.evaluate { [weak self] (success, error) in

                            print("start self.evaluate")

                            if success {

                                guideMsg = "생체인증이 완료되었습니다."

                                onCompletion(100, self!.auto_login_url, guideMsg, self?.dictForMain ?? [:])

                                print(guideMsg)

                            } else {

                                guideMsg = error?.localizedDescription ?? "Face ID/Touch ID may not be configured"

                                onCompletion(3, "onlyViewToast", guideMsg, self?.dictForMain ?? [:])

                            }

                        }

                    } else {

                        onCompletion(3, "onlyViewToast", "생체인증을 먼저 등록해 주십시오.", dictForMain)

                    }

                }

            }

        }

    }

    func bioInfoRegister() {

        var sql = "delete from " + tbl_member

        sql = sql + " where site_code='" + site_code! + "' and data_type='biometric'"

        dbManagerMember.sql_query(sql: sql)

        

        dbManagerMember.insertData(data_type: "biometric", site_code: site_code!, domain_url: domain_url!, userid_ori: userid_ori!, userid: userid!, userpwd_ori: "", usertype: "", login_date: login_date!)

    }

    func bioInfoCheckFromTable() -> Bool {

        var is_exist = false

        let arr_login: [MyModel] = dbManagerMember.get_from_member_table_login_info(command: "biometric", site_code_para: site_code!)

        if arr_login.count > 0 {

            let idx = arr_login[0].idx

            let data_type = arr_login[0].data_type

            let site_code = arr_login[0].site_code;

            let domain_url = arr_login[0].domain_url;

            let userid_ori = arr_login[0].userid_ori;

            let userid = arr_login[0].userid;

            let userpwd_ori = arr_login[0].userpwd_ori;

            let usertype = arr_login[0].usertype;

            let login_date = arr_login[0].login_date;

        

            var url_tmp2 = domain_url;

            url_tmp2 = url_tmp2 + "/member/login_auto_for_app.php";

            url_tmp2 = url_tmp2 + "?site_code=" + site_code;

            url_tmp2 = url_tmp2 + "&userid=" + userid;

            url_tmp2 = url_tmp2 + "&userpwd_ori=" + userpwd_ori;

            url_tmp2 = url_tmp2 + "&usertype=" + usertype;

            url_tmp2 = url_tmp2 + "&login_date=" + (login_date.urlEncoded ?? "");

            url_tmp2 = url_tmp2 + "&login_type=bioAuthLater";

            url_tmp2 = url_tmp2 + "&return_url=" + (return_url.urlEncoded ?? "");

            

            auto_login_url = url_tmp2;

            is_exist = true;

        }

        return is_exist

    }

    

    func canEvaluate(completion: (Bool, BiometricType, BiometricError?) -> Void) {

        guard context.canEvaluatePolicy(policy, error: &error) else {

            let type = biometricType(for: context.biometryType)

            

            guard let error = error else {

                return completion(false, type, nil)

            }

            

            return completion(false, type, biometricError(from: error))

        }

        

        completion(true, biometricType(for: context.biometryType), nil)

    }

    

    func evaluate(completion: @escaping (Bool, BiometricError?) -> Void) {

        print("start evaluate") // will_delete

        context.evaluatePolicy(policy, localizedReason: localizedReason) { [weak self] success, error in

            print("evaluate 1") // will_delete

            DispatchQueue.main.async {

                if success {

                    print("evaluate 2 success") // will_delete

                    completion(true, nil)

                } else {

                    print("evaluate 3 failed") // will_delete

                    guard let error = error else { return completion(false, nil) }

                    

                    completion(false, self?.biometricError(from: error as NSError))

                }

            }

        }

    }

    

    private func biometricType(for type: LABiometryType) -> BiometricType {

        switch type {

        case .none:

            return .none

        case .touchID:

            return .touchID

        case .faceID:

            return .faceID

        @unknown default:

            return .unknown

        }

    }

    

    private func biometricError(from nsError: NSError) -> BiometricError {

        let error: BiometricError

        

        switch nsError {

        case LAError.authenticationFailed:

            error = .authenticationFailed

        case LAError.userCancel:

            error = .userCancel

        case LAError.userFallback:

            error = .userFallback

        case LAError.biometryNotAvailable:

            error = .biometryNotAvailable

        case LAError.biometryNotEnrolled:

            error = .biometryNotEnrolled

        case LAError.biometryLockout:

            error = .biometryLockout

        default:

            error = .unknown

        }

        

        return error

    }

 

}

 

                    
  1. iOS개발질문방 이용안내 (등록포인트:100, 답변:100, 추천: 500)

    Date2015.03.01 By아이폰데브 Reply1 Views2326 Votes8
    read more
  2. wkwebview에서 post방식으로 외부 브라우저 호출하기

    Date2023.09.04 CategoryiOS 일반 Byrandychoi Reply1 Views169 Votes0
    Read More
  3. 하이브리드 앱 카카오톡 공유 하는 법 알려주세요..

    Date2023.08.24 CategoryiOS 일반 By쇠고기다시다 Reply2 Views166 Votes0 file
    Read More
  4. 안녕하세요 웹앱 개발 중 window.open 후 window.close에서 webViewDidClose 이벤트가 반응이 없습니다.

    Date2023.08.18 CategorySwift문법 By한한한 Reply2 Views155 Votes0
    Read More
  5. ios 폰트에서 텍스트 스타일을 만들 수 있나요?

    Date2023.08.16 CategoryXcode Bymori Reply1 Views131 Votes0
    Read More
  6. 요청할 때마다 무조건 생체인증(Face ID) 화면을 띄우고 싶습니다

    Date2023.08.16 CategorySwift문법 By청소부 Reply0 Views180 Votes0
    Read More
  7. MVVM 에서 팝업 관련 질문이 있습니다.

    Date2023.08.14 CategoryiOS 일반 Bysmartrain Reply0 Views187 Votes0
    Read More
  8. 4.3 심사 거절 spam

    Date2023.08.07 CategoryiOS 일반 By희하후 Reply3 Views243 Votes0
    Read More
  9. ScreenTimeAPI 에 대해 질문드립니다.

    Date2023.08.07 CategoryiOS 일반 Bypeppo Reply0 Views156 Votes0
    Read More
  10. SNS 애플 로그인 버튼

    Date2023.08.05 CategorySwiftUI Bymas1013 Reply2 Views137 Votes0 file
    Read More
  11. XCFramework를 만들때 안에 Pod Library있는 경우,

    Date2023.08.04 CategoryiOS 일반 By겸군님 Reply3 Views115 Votes1 file
    Read More
  12. swift suspended관련 ble auto connect구현 방법 질문

    Date2023.07.31 CategoryiOS 일반 By아이폰초보중에초보 Reply0 Views118 Votes0
    Read More
  13. 프로비저닝 프로파일 갱신 질문드립니다.

    Date2023.07.27 CategoryiOS 일반 ByHarry_kor Reply0 Views135 Votes0
    Read More
  14. 블루투스 클래식 샘플코드 구할수 있을까요?

    Date2023.07.24 Category블루투스 By여행스케치 Reply0 Views140 Votes0
    Read More
  15. 자릿수 맞춰서 출력하기?

    Date2023.07.22 CategoryiOS 일반 Byios초보중의초보 Reply1 Views109 Votes0
    Read More
  16. 알고리즘 자료구조 공부에 관해 질문

    Date2023.07.16 CategoryiOS 일반 By그랑디스 Reply2 Views117 Votes0
    Read More
  17. 하나의 뷰 컨트롤러 디자인에 여러 클래스 사용하기??

    Date2023.07.16 CategoryiOS 일반 Byios초보중의초보 Reply4 Views113 Votes0
    Read More
  18. 사용자가 특정앱을 다운 받았는지 알 수 있나요??

    Date2023.07.15 CategoryiOS 일반 Byspecificprogram Reply1 Views128 Votes0
    Read More
  19. CoreBluetooth 관련 질문

    Date2023.07.11 Category블루투스 ByHiroSH Reply2 Views111 Votes0
    Read More
  20. SwiftUI 이용한 UIActivityViewController 사용 문의

    Date2023.07.10 CategorySwiftUI Byevan Reply0 Views108 Votes0
    Read More
  21. UIPageViewController Transition Custom

    Date2023.07.10 Category애니메이션 By여러가지개발 Reply0 Views83 Votes0
    Read More
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 140 Next
/ 140
회원수   전체 : 14,413   오늘 : 0   어제 : 1   |   방문자수   전체 : 3,383,721   오늘 : 317   어제 : 1,129   |   페이지뷰   전체 : 46,972,301   오늘 : 2,131   어제 : 4,404  

 
© 스위프톡. All Rights Reserved.

sketchbook5, 스케치북5

sketchbook5, 스케치북5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소