Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

개발일기 #8 : 나의 앱에도 지문인증을 넣어보자.

Billcorea 2022. 11. 1. 00:45
반응형

바이오인증

앱을 구현하는 동안 이런 것도 생각을 해 볼 수 있었습니다.  지문인증은 어떻게 구현하는 건가?

그래서 구글에게 물어보았습니다. 어떻게 하는 거냐고...  늘 항상 답을 보여 주기는 하나 긴가 민가 하는 생각이 들 무렵 게시글 하나를 찾았고 그것을 따라 해 보기로 했습니다. 

 

gradle 설정

// bio
implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05"

 module 수준의 gradle 파일에 추가된 것은 위 한 줄입니다. 

 

Hardware 검증

이번에는 지문 인증을 사용할 수 있는 것인지 확인하는 처리를 해 봅니다.   아래 코드의 함수를 호출하게 되면, 

사용이 가능한 상태 (BIOMETRIC_SUCCESS),

지문인식 센서가 없는 경우(BIOMETRIC_ERROR_NO_HARDWARE),

지문인식 센서가 이미 동작하고 있어서 준비가 되지 않은 경우(BIOMETRIC_ERROR_HW_UNAVAILABLE)

지문이 등록되지 않은 경우(BIOMETRIC_ERROR_NONE_ENROLLED)

 

이런 경우의 오류(또는 상태)를 만나게 됩니다.  지문 등록이 되지 않은 경우는 등록을 하도록 안내하는 페이지로 이동하도록 구성하고, 다른 경우들은 그에 맞게 알림을 주거나 인증 후 동작을 구현하게 됩니다.  여기서는 사용 가능한 상태만 저장하는 것으로 마무리를 합니다.

fun checkDeviceHasBiometric() {
    val biometricManager = BiometricManager.from(this)
    when (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL)) {
        BiometricManager.BIOMETRIC_SUCCESS -> {
            Log.e("MY_APP_TAG", "App can authenticate using biometrics.")
            info = getString(R.string.biometric_success) // "App can authenticate using biometrics."
            productsViewModel.isBioAuth.value = true

        }
        BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
            Log.e("MY_APP_TAG", "No biometric features available on this device.")
            info = getString(R.string.biometric_error_no_hardware) // "No biometric features available on this device."
            productsViewModel.isBioAuth.value = false

        }
        BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
            Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
            info = getString(R.string.biometric_error_hw_unavailable) // "Biometric features are currently unavailable."
            productsViewModel.isBioAuth.value = false

        }
        BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
            // Prompts the user to create credentials that your app accepts.
            val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
                putExtra(
                    Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                    BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL
                )
            }
            productsViewModel.isBioEnabled.value = false

            startActivityIfNeeded(enrollIntent, BIOMETRIC_CODE)
        }
    }
}

 

지문 인식 하기

다음 코드의 함수와 같이 작성하게 되면, 하드 웨어 적인 지문 인식 기능을 사용할 수 있게 됩니다.

promptInfo의 속성들을 보면 화면에 보여줄 제목과 상세 설명 등을 설정할 수 있으니 그것에 앱의 기능 구현에 필요한 상태에 따라서 제목, 메시지 등을 추가할 수 있습니다.

 

biometricPrompt을 호출해 주는 것으로 동작이 실행되는 것을 볼 수 있습니다. 여기서는 지문 인증이 잘 되었는지에 따라서 다음 동작을 구현해 볼 수 있습니다.

private fun doFingerPrint() {
    val promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle(getString(R.string.biometric_prompt_title))
        .setSubtitle(getString(R.string.biometric_prompt_description))
        .setNegativeButtonText(getString(android.R.string.cancel))
        .build()

    val biometricPrompt = BiometricPrompt(
        this@MainActivity,
        object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(
                errorCode: Int,
                errString: CharSequence
            ) {
                if (errorCode !in biometricsIgnoredErrors) {
                    Toast.makeText(
                        this@MainActivity,
                        getString(R.string.biometric_error, errString),
                        Toast.LENGTH_LONG
                    ).show()
                }
                productsViewModel.isBioEnabled.value = false
            }
            override fun onAuthenticationSucceeded(
                result: BiometricPrompt.AuthenticationResult
            ) {
                productsViewModel.isBioEnabled.value = true
            }
            override fun onAuthenticationFailed() {
                Toast.makeText(
                    this@MainActivity,
                    R.string.biometric_authentication_error,
                    Toast.LENGTH_LONG
                ).show()
                productsViewModel.isBioEnabled.value = true
            }
        }
    )

    biometricPrompt.authenticate(promptInfo)
}

 

활용 예시

이렇게 아래 화면과 같은 기능이 구현 가능해집니다.  이전 화면에서 지문인식 동작하는 버튼을 클릭하면 아래 그림과 같이 팝업 안내창이 나오고 지문 인식 대기 상태가 되어 사용자가 지문을 클릭 하면 위 코드와 같이 다음 동작으로 넘어가는 기능 구현을 할 수 있게 됩니다.

지문인식사용 예시

 

참고자료

이번 글의 재료는 아래 링크에서 참조했음을 밝혀 둡니다.  다음번에는 아래 링크의 내용 중에서 PIN을 입력받는 코드 구현을 해 볼까 합니다.

https://medium.com/@fvilarino/adding-a-pin-screen-with-biometric-authentication-in-jetpack-co mpose-a9bf7bd8acc9

 

Adding a PIN screen with biometric authentication in Jetpack Compose

In this article we’ll find out how to add biometric authentication to an Android app developed with Jetpack Compose. As not all devices…

fvilarino.medium.com

 

반응형