Şifre anahtarıyla oturum açma

Bu rehberde, kimlik doğrulama için geçiş anahtarı kullanma konusundaki uygulamaya devam edilmektedir. Kullanıcılarınızın geçiş anahtarlarıyla oturum açabilmesi için Geçiş anahtarı oluşturma bölümündeki talimatları da uygulamanız gerekir.

Geçiş anahtarıyla kimlik doğrulaması yapmak için önce uygulama sunucunuzdan ortak anahtarı almak üzere gereken seçenekleri almanız, ardından ortak anahtarı almak için Credential Manager API'yi çağırmanız gerekir. Ardından, oturum açma yanıtını uygun şekilde işleyin.

Genel Bakış

Bu kılavuz, kullanıcınızın geçiş anahtarıyla oturum açması için istemci uygulamanızda yapılması gereken değişikliklere odaklanır ve uygulama sunucusu tarafı uygulaması hakkında kısa bir genel bakış sunar. Sunucu tarafı entegrasyonu hakkında daha fazla bilgi edinmek için Sunucu tarafı geçiş anahtarı kimlik doğrulaması başlıklı makaleyi inceleyin.

Kullanıcının hesabıyla ilişkili tüm geçiş anahtarı ve şifre seçeneklerini almak için aşağıdaki adımları tamamlayın:

  1. Sunucudan kimlik bilgisi isteği seçeneklerini alma: Geçiş anahtarıyla oturum açma sürecini başlatmak için uygulamanızdan kimlik doğrulama sunucunuza istekte bulunun. Sunucudan, ortak anahtar kimlik bilgisini almak için gereken seçenekleri ve benzersiz bir sorguyu gönderin.
  2. Herkese açık anahtar kimlik bilgisi almak için gereken nesneyi oluşturun: Sunucu tarafından gönderilen seçenekleri bir GetPublicKeyCredentialOption nesnesine sarmalayın.
  3. (isteğe bağlı) getCredential'ı hazırlayın: Android 14 ve sonraki sürümlerde, getCredential() çağrılmadan önce prepareGetCredential() yöntemini kullanarak hesap seçiciyi göstererek gecikmeyi azaltabilirsiniz.
  4. Oturum açma akışını başlatın: Kullanıcının oturum açması için getCredential() yöntemini çağırın.
  5. Yanıtı işleme: Olası kimlik bilgisi yanıtlarının her birini işleyin.
  6. İstisnaları ele alma: İstisnaları uygun şekilde ele aldığınızdan emin olun.

1. Sunucudan kimlik bilgisi isteği seçeneklerini alma

Herkese açık anahtar kimlik bilgilerini almak için gereken seçeneklerin yanı sıra her oturum açma denemesi için benzersiz olan challenge değerini sunucudan isteyin. Sunucu tarafı uygulama hakkında daha fazla bilgi edinmek için Zorluk oluşturma ve Kimlik bilgisi isteği seçenekleri oluşturma başlıklı makalelere bakın.

Seçenekler aşağıdakilere benzer:

{
  "challenge": "<your app challenge>",
  "allowCredentials": [],
  "rpId": "<your app server domain>"
}

Alanlar hakkında daha fazla bilgi edinmek için Geçiş anahtarıyla oturum açma hakkındaki blog gönderisini inceleyin.

2. Ortak anahtar kimlik bilgisi almak için gereken nesneyi oluşturun.

Uygulamanızda, GetPublicKeyCredentialOption nesnesi oluşturmak için seçenekleri kullanın. Aşağıdaki örnekte requestJson, sunucu tarafından gönderilen seçenekleri temsil eder.

// Get password logins from the credential provider on the user's device.
val getPasswordOption = GetPasswordOption()

// Get passkeys from the credential provider on the user's device.
val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(
    requestJson = requestJson
)

Ardından, GetPublicKeyCredentialOption öğesini GetCredentialRequest nesnesiyle sarmalayın.

val credentialRequest = GetCredentialRequest(
    // Include all the sign-in options that your app supports.
    listOf(getPasswordOption, getPublicKeyCredentialOption),
    // Defines whether you prefer to use only immediately available
    // credentials or hybrid credentials.
    preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
)

3. İsteğe bağlı: Oturum açma gecikmesini azaltma

Android 14 veya sonraki sürümlerde, getCredential() işlevini çağırmadan önce prepareGetCredential() yöntemini kullanarak hesap seçiciyi gösterirken gecikmeyi azaltabilirsiniz.

prepareGetCredential() yöntemi, önbelleğe alınan bir PrepareGetCredentialResponse nesnesi döndürür. Bu, sonraki adımda getCredential() yönteminin, önbelleğe alınmış verilerle hesap seçiciyi açmasına olanak tanır.

coroutineScope {
    val response = credentialManager.prepareGetCredential(
        GetCredentialRequest(
            listOf(
                // Include all the sign-in options that your app supports
                getPublicKeyCredentialOption, 
                getPasswordOption
            )
        )
    )
}

4. Oturum açma akışını başlatma

Kullanıcıya hesap seçiciyi göstermek için getCredential() yöntemini çağırın. Oturum açma akışını nasıl başlatacağınızla ilgili referans olarak aşağıdaki kod snippet'ini kullanın:

coroutineScope {
    try {
        result = credentialManager.getCredential(
            // Use an activity-based context to avoid undefined system UI
            // launching behavior.
            context = activityContext,
            request = credentialRequest
        )
        handleSignIn(result)
    } catch (e: GetCredentialException) {
        // Handle failure
    }
}

5. Yanıtı işleme

Çeşitli kimlik bilgisi nesnesi türlerinden birini içerebilen yanıtı işleyin.

fun handleSignIn(result: GetCredentialResponse) {
    // Handle the successfully returned credential.
    val credential = result.credential

    when (credential) {
        is PublicKeyCredential -> {
            val responseJson = credential.authenticationResponseJson
            // Share responseJson i.e. a GetCredentialResponse on your server to
            // validate and  authenticate
        }

        is PasswordCredential -> {
            val username = credential.id
            val password = credential.password
            // Use id and password to send to your server to validate
            // and authenticate
        }

        is CustomCredential -> {
            // If you are also using any external sign-in libraries, parse them
            // here with the utility functions provided.
            if (credential.type == ExampleCustomCredential.TYPE) {
                try {
                    val ExampleCustomCredential =
                        ExampleCustomCredential.createFrom(credential.data)
                    // Extract the required credentials and complete the authentication as per
                    // the federated sign in or any external sign in library flow
                } catch (e: ExampleCustomCredential.ExampleCustomCredentialParsingException) {
                    // Unlikely to happen. If it does, you likely need to update the dependency
                    // version of your external sign-in library.
                    Log.e(TAG, "Failed to parse an ExampleCustomCredential", e)
                }
            } else {
                // Catch any unrecognized custom credential type here.
                Log.e(TAG, "Unexpected type of credential")
            }
        }
        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential")
        }
    }
}

Kimlik doğrulama işleminden döndürülen PublicKeyCredential, temelde aşağıdaki gibi yapılandırılmış imzalı bir onaydır:

{
  "id": "<credential ID>",
  "type": "public-key",
  "rawId": "<raw credential ID>",
  "response": {
    "clientDataJSON": "<signed client data containing challenge>",
    "authenticatorData": "<authenticator metadata>",
    "signature": "<digital signature to be verified>",
    "userHandle": "<user ID from credential registration>"
  }
}

Sunucuda kimlik bilgisini doğrulamanız gerekir. Daha fazla bilgi için Kullanıcıyı doğrulama ve kullanıcının oturum açmasını sağlama başlıklı makaleyi inceleyin.

6. İstisnaları işleme

GetCredentialException sınıfının tüm alt sınıf istisnalarını ele almanız gerekir. Her bir istisnayı nasıl ele alacağınızı öğrenmek için sorun giderme kılavuzuna bakın.

coroutineScope {
    try {
        result = credentialManager.getCredential(
            context = activityContext,
            request = credentialRequest
        )
    } catch (e: GetCredentialException) {
        Log.e("CredentialManager", "No credential available", e)
    }
}

Sonraki adımlar