Kimlik Yöneticisi ile kullanıcınızda oturum açın

Kimlik Bilgisi Yöneticisi, kullanıcı adı ve şifre, geçiş anahtarları ve birleşik oturum açma çözümleri (ör. Google ile oturum açma) gibi birden fazla oturum açma yöntemini tek bir API'de destekleyen bir Jetpack API'sidir. Bu sayede geliştiriciler için entegrasyonu kolaylaştırır.

Ayrıca, kimlik bilgisi yöneticisi, kimlik doğrulama yöntemleri arasında oturum açma arayüzünü birleştirir. Bu sayede kullanıcılar hangi yöntemi seçerse seçsin uygulamalarda daha kolay ve anlaşılır bir şekilde oturum açabilirler.

Bu sayfada, geçiş anahtarı kavramı ve kimlik bilgisi yöneticisi API'sini kullanarak geçiş anahtarları da dahil olmak üzere kimlik doğrulama çözümleri için istemci tarafı desteğini uygulama adımları açıklanmaktadır. Ayrıca, daha ayrıntılı ve spesifik sorulara yanıt veren ayrı bir SSS sayfası da vardır.

Geri bildiriminiz, Credential Manager API'nin iyileştirilmesinde önemli bir rol oynar. Karşılaştığınız sorunları veya API'yi iyileştirmeyle ilgili fikirlerinizi aşağıdaki bağlantıyı kullanarak paylaşın:

Geri bildirim gönderin

Geçiş anahtarları hakkında

Geçiş anahtarları, şifrelere kıyasla daha güvenli ve kolay bir alternatiftir. Geçiş anahtarları sayesinde kullanıcılar, biyometrik sensör (ör. parmak izi veya yüz tanıma), PIN ya da desen kullanarak uygulamalarda ve web sitelerinde oturum açabilir. Bu sayede, kullanıcılarınıza sorunsuz bir oturum açma deneyimi sunabilir ve kullanıcı adlarını ya da şifreleri hatırlama zorunluluğundan kurtarabilirsiniz.

Geçiş anahtarları, FIDO Alliance ve World Wide Web Consortium (W3C) tarafından ortaklaşa geliştirilen bir standart olan WebAuthn'e (Web Kimlik Doğrulaması) dayanır. WebAuthn, kullanıcının kimliğini doğrulamak için ortak anahtar kriptografisini kullanır. Kullanıcının oturum açtığı web sitesi veya uygulama, herkese açık anahtarı görebilir ve saklayabilir ancak gizli anahtarı hiçbir zaman göremez veya saklayamaz. Özel anahtar gizli ve güvenli bir şekilde saklanır. Anahtar benzersiz olduğu ve web sitesine ya da uygulamaya bağlı olduğu için geçiş anahtarları kimlik avı saldırılarına karşı korunur ve daha fazla güvenlik sağlar.

Kimlik Bilgisi Yöneticisi, kullanıcıların geçiş anahtarları oluşturup bunları Google Şifre Yöneticisi'nde saklamasına olanak tanır.

Kimlik Bilgisi Yöneticisi ile sorunsuz geçiş anahtarı kimlik doğrulama akışlarının nasıl uygulanacağı hakkında bilgi edinmek için Geçiş anahtarlarıyla kullanıcı kimlik doğrulaması başlıklı makaleyi okuyun.

Ön koşullar

Kimlik Bilgisi Yöneticisi'ni kullanmak için bu bölümdeki adımları tamamlayın.

Platformun güncel bir sürümünü kullanın

Kimlik Bilgisi Yöneticisi, Android 4.4 (API düzeyi 19) ve sonraki sürümlerde desteklenir.

Uygulamanıza bağımlılık ekleme

Uygulama modülünüzün derleme komut dosyasına aşağıdaki bağımlılıkları ekleyin:

Kotlin

dependencies {
    implementation("androidx.credentials:credentials:1.5.0-alpha05")

    // optional - needed for credentials support from play services, for devices running
    // Android 13 and below.
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0-alpha05")
}

Eski

dependencies {
    implementation "androidx.credentials:credentials:1.5.0-alpha05"

    // optional - needed for credentials support from play services, for devices running
    // Android 13 and below.
    implementation "androidx.credentials:credentials-play-services-auth:1.5.0-alpha05"
}

ProGuard dosyasında sınıfları koruma

Modülünüzün proguard-rules.pro dosyasına aşağıdaki talimatları ekleyin:

-if class androidx.credentials.CredentialManager
-keep class androidx.credentials.playservices.** {
  *;
}

Uygulamanızı küçültme, karartma ve optimize etme hakkında daha fazla bilgi edinin.

Digital Asset Links desteği ekleme

Android uygulamanız için geçiş anahtarı desteğini etkinleştirmek üzere uygulamanızı, sahibi olduğunuz bir web sitesiyle ilişkilendirin. Aşağıdaki adımları uygulayarak bu ilişkilendirmeyi belirtebilirsiniz:

  1. Digital Asset Links JSON dosyası oluşturun. Örneğin, https://signin.example.com web sitesinin ve com.example paket adına sahip bir Android uygulamasının oturum açma kimlik bilgilerini paylaşabileceğini belirtmek için aşağıdaki içeriği içeren assetlinks.json adlı bir dosya oluşturun:

    [
      {
        "relation" : [
          "delegate_permission/common.handle_all_urls",
          "delegate_permission/common.get_login_creds"
        ],
        "target" : {
          "namespace" : "android_app",
          "package_name" : "com.example.android",
          "sha256_cert_fingerprints" : [
            SHA_HEX_VALUE
          ]
        }
      }
    ]
    

    relation alanı, tanımlanan ilişkiyi açıklayan bir veya daha fazla dize dizisidir. Uygulamaların ve sitelerin oturum açma kimliklerini paylaştığını belirtmek için ilişkileri delegate_permission/handle_all_urls ve delegate_permission/common.get_login_creds olarak belirtin.

    target alanı, beyanın geçerli olduğu öğeyi belirten bir nesnedir. Aşağıdaki alanlar bir web sitesini tanımlar:

    namespace web
    site

    Web sitesinin URL'si, https://domain[:optional_port] biçiminde (ör. https://www.example.com).

    domain tam nitelikli olmalıdır ve HTTPS için 443 numaralı bağlantı noktası kullanıldığında optional_port atlanmalıdır.

    site hedefi yalnızca bir kök alan olabilir: Bir uygulama ilişkilendirmesini belirli bir alt dizinle sınırlayamazsınız. URL'ye yol (ör. son eğik çizgi) eklemeyin.

    Alt alanların eşleştiği kabul edilmez. Yani domain alan adını www.example.com olarak belirtirseniz www.counter.example.com alanı uygulamanızla ilişkilendirilmez.

    Aşağıdaki alanlar bir Android uygulamasını tanımlar:

    namespace android_app
    package_name Uygulamanın manifest dosyasında beyan edilen paket adı. Örneğin: com.example.android
    sha256_cert_fingerprints Uygulamanızın imza sertifikasının SHA256 parmak izleri.
  2. Digital Asset Links JSON dosyasını, oturum açma alanındaki aşağıdaki konumda barındırın:

    https://domain[:optional_port]/.well-known/assetlinks.json
    

    Örneğin, oturum açma alanınız signin.example.com ise JSON dosyasını https://signin.example.com/.well-known/assetlinks.json adresinde barındırın.

    Digital Asset Links dosyasının MIME türünün JSON olması gerekir. Sunucunun yanıtta Content-Type: application/json üstbilgisi gönderdiğinden emin olun.

  3. Barındırma sağlayıcınızın, Google'ın Digital Asset Link dosyanızı almasına izin verdiğinden emin olun. robots.txt dosyanız varsa Googlebot aracısının /.well-known/assetlinks.json'i almasına izin vermelidir. Çoğu site, diğer hizmetlerin bu dosyalardaki meta verilere erişebilmesi için tüm otomatik aracıların /.well-known/ yolundaki dosyaları almasına izin verebilir:

    User-agent: *
    Allow: /.well-known/
    
  4. Manifest dosyasına <application> altında aşağıdaki satırı ekleyin:

    <meta-data android:name="asset_statements" android:resource="@string/asset_statements" />
    
  5. Kimlik Bilgisi Yöneticisi aracılığıyla şifre ile oturum açıyorsanız manifest dosyasında dijital öğe bağlamayı yapılandırmak için bu adımı uygulayın. Yalnızca geçiş anahtarları kullanıyorsanız bu adım gerekli değildir.

    Android uygulamasında ilişkilendirmeyi beyan edin. Yüklenecek assetlinks.json dosyalarını belirten bir nesne ekleyin. Dizide kullandığınız apostrof ve tırnak işaretlerinden kurtulmanız gerekir. Örnek:

    <string name="asset_statements" translatable="false">
    [{
      \"include\": \"https://signin.example.com/.well-known/assetlinks.json\"
    }]
    </string>
    
    > GET /.well-known/assetlinks.json HTTP/1.1
    > User-Agent: curl/7.35.0
    > Host: signin.example.com
    
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    

Kimlik Bilgisi Yöneticisi'ni yapılandırma

Bir CredentialManager nesnesini yapılandırmak ve başlatmak için aşağıdakine benzer bir mantık ekleyin:

Kotlin

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
val credentialManager = CredentialManager.create(context)

Java

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
CredentialManager credentialManager = CredentialManager.create(context)

Kimlik bilgisi alanlarını belirtme

Android 14 ve sonraki sürümlerde isCredential özelliği, kullanıcı adı veya şifre alanları gibi kimlik bilgisi alanlarını belirtmek için kullanılabilir. Bu özellik, bu görünümün Kimlik Bilgisi Yöneticisi ve üçüncü taraf kimlik bilgisi sağlayıcılarla çalışacak şekilde tasarlanmış bir kimlik bilgisi alanı olduğunu ve otomatik doldurma hizmetlerinin daha iyi otomatik doldurma önerileri sunmasına yardımcı olduğunu gösterir. Uygulama, Kimlik Bilgisi Yöneticisi API'sini kullandığında, mevcut kimlik bilgilerini içeren Kimlik Bilgisi Yöneticisi alt sayfası gösterilir ve kullanıcı adı veya şifre için otomatik doldurma doldurma iletişim kutusunu göstermeye gerek kalmaz. Benzer şekilde, uygulama kimlik bilgilerini kaydetmek için Kimlik Bilgisi Yöneticisi API'sini isteyeceğinden, otomatik doldurma özelliğinin şifreler için kaydetme iletişim kutusunu göstermesine gerek yoktur.

isCredential özelliğini kullanmak için ilgili Görünümlere ekleyin:

<TextView
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:isCredential="true"
...
 />

Kullanıcınızda oturum açma

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ı uygulayın:

  1. Şifre ve şifre anahtarı kimlik doğrulama seçeneklerini başlatın:

    Kotlin

    // Retrieves the user's saved password for your app from their
    // password provider.
    val getPasswordOption = GetPasswordOption()
    
    // Get passkey from the user's public key credential provider.
    val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(
        requestJson = requestJson
    )

    Java

    // Retrieves the user's saved password for your app from their
    // password provider.
    GetPasswordOption getPasswordOption = new GetPasswordOption();
    
    // Get passkey from the user's public key credential provider.
    GetPublicKeyCredentialOption getPublicKeyCredentialOption =
            new GetPublicKeyCredentialOption(requestJson);
  2. Oturum açma isteğini oluşturmak için önceki adımdan alınan seçenekleri kullanın.

    Kotlin

    val getCredRequest = GetCredentialRequest(
        listOf(getPasswordOption, getPublicKeyCredentialOption)
    )

    Java

    GetCredentialRequest getCredRequest = new GetCredentialRequest.Builder()
        .addCredentialOption(getPasswordOption)
        .addCredentialOption(getPublicKeyCredentialOption)
        .build();
  3. Oturum açma akışını başlatın:

    Kotlin

    coroutineScope.launch {
        try {
            val result = credentialManager.getCredential(
                // Use an activity-based context to avoid undefined system UI
                // launching behavior.
                context = activityContext,
                request = getCredRequest
            )
            handleSignIn(result)
        } catch (e : GetCredentialException) {
            handleFailure(e)
        }
    }
    
    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")
            }
        }
    }

    Java

    credentialManager.getCredentialAsync(
        // Use activity based context to avoid undefined
        // system UI launching behavior
        activity,
        getCredRequest,
        cancellationSignal,
        <executor>,
        new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
            @Override
            public void onResult(GetCredentialResponse result) {
                handleSignIn(result);
            }
    
            @Override
            public void onError(GetCredentialException e) {
                handleFailure(e);
            }
        }
    );
    
    public void handleSignIn(GetCredentialResponse result) {
        // Handle the successfully returned credential.
        Credential credential = result.getCredential();
        if (credential instanceof PublicKeyCredential) {
            String responseJson = ((PublicKeyCredential) credential).getAuthenticationResponseJson();
            // Share responseJson i.e. a GetCredentialResponse on your server to validate and authenticate
        } else if (credential instanceof PasswordCredential) {
            String username = ((PasswordCredential) credential).getId();
            String password = ((PasswordCredential) credential).getPassword();
            // Use id and password to send to your server to validate and authenticate
        } else if (credential instanceof CustomCredential) {
            if (ExampleCustomCredential.TYPE.equals(credential.getType())) {
                try {
                    ExampleCustomCredential customCred = ExampleCustomCredential.createFrom(customCredential.getData());
                    // Extract the required credentials and complete the
                    // authentication as per the federated sign in or any external
                    // sign in library flow
                } catch (ExampleCustomCredential.ExampleCustomCredentialParsingException e) {
                    // 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");
        }
    }

Aşağıdaki örnekte, geçiş anahtarı aldığınızda JSON isteğini nasıl biçimlendireceğiniz gösterilmektedir:

{
  "challenge": "T1xCsnxM2DNL2KdK5CLa6fMhD7OBqho6syzInk_n-Uo",
  "allowCredentials": [],
  "timeout": 1800000,
  "userVerification": "required",
  "rpId": "credential-manager-app-test.glitch.me"
}

Aşağıdaki örnekte, herkese açık anahtar kimlik bilgisi aldıktan sonra JSON yanıtının nasıl görünebileceği gösterilmektedir:

{
  "id": "KEDetxZcUfinhVi6Za5nZQ",
  "type": "public-key",
  "rawId": "KEDetxZcUfinhVi6Za5nZQ",
  "response": {
    "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiVDF4Q3NueE0yRE5MMktkSzVDTGE2Zk1oRDdPQnFobzZzeXpJbmtfbi1VbyIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",
    "authenticatorData": "j5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGQdAAAAAA",
    "signature": "MEUCIQCO1Cm4SA2xiG5FdKDHCJorueiS04wCsqHhiRDbbgITYAIgMKMFirgC2SSFmxrh7z9PzUqr0bK1HZ6Zn8vZVhETnyQ",
    "userHandle": "2HzoHm_hY0CjuEESY9tY6-3SdjmNHOoNqaPDcZGzsr0"
  }
}

Kimlik bilgisi olmadığında istisnaları işleme

Bazı durumlarda kullanıcının kimlik bilgisi olmayabilir veya mevcut bir kimlik bilgisinin kullanılmasına izin vermeyebilir. getCredential() çağrılırsa ve kimlik bilgileri bulunamazsa NoCredentialException döndürülür. Bu durumda, kodunuz NoCredentialException örneklerini işlemelidir.

Kotlin

try {
  val credential = credentialManager.getCredential(credentialRequest)
} catch (e: NoCredentialException) {
  Log.e("CredentialManager", "No credential available", e)
}

Java

try {
  Credential credential = credentialManager.getCredential(credentialRequest);
} catch (NoCredentialException e) {
  Log.e("CredentialManager", "No credential available", e);
}

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

Kotlin

val response = credentialManager.prepareGetCredential(
  GetCredentialRequest(
    listOf(
      <getPublicKeyCredentialOption>,
      <getPasswordOption>
    )
  )
}

Java

GetCredentialResponse response = credentialManager.prepareGetCredential(
  new GetCredentialRequest(
    Arrays.asList(
      new PublicKeyCredentialOption(),
      new PasswordOption()
    )
  )
);

prepareGetCredential() yöntemi kullanıcı arayüzü öğelerini çağırmaz. Yalnızca hazırlık çalışmalarını gerçekleştirmenize yardımcı olur. Böylece, daha sonra getCredential() API aracılığıyla kalan kimlik bilgisi alma işlemini (kullanıcı arayüzlerini içerir) başlatabilirsiniz.

Önbelleğe alınan veriler bir PrepareGetCredentialResponse nesnesi olarak döndürülür. Mevcut kimlik bilgileri varsa sonuçlar önbelleğe alınır ve daha sonra önbelleğe alınmış verilerle hesap seçiciyi açmak için kalan getCredential() API'yi başlatabilirsiniz.

Kayıt akışları

Geçiş anahtarı veya şifre kullanarak bir kullanıcıyı kimlik doğrulaması için kaydedebilirsiniz.

Geçiş anahtarı oluşturun

Kullanıcılara geçiş anahtarı kaydetme ve bunu yeniden kimlik doğrulama için kullanma seçeneği sunmak istiyorsanız CreatePublicKeyCredentialRequest nesnesi kullanarak bir kullanıcı kimlik bilgisi kaydedin.

Kotlin

fun createPasskey(requestJson: String, preferImmediatelyAvailableCredentials: Boolean) {
    val createPublicKeyCredentialRequest = CreatePublicKeyCredentialRequest(
        // Contains the request in JSON format. Uses the standard WebAuthn
        // web JSON spec.
        requestJson = requestJson,
        // Defines whether you prefer to use only immediately available
        // credentials, not hybrid credentials, to fulfill this request.
        // This value is false by default.
        preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
    )

    // Execute CreateCredentialRequest asynchronously to register credentials
    // for a user account. Handle success and failure cases with the result and
    // exceptions, respectively.
    coroutineScope.launch {
        try {
            val result = credentialManager.createCredential(
                // Use an activity-based context to avoid undefined system
                // UI launching behavior
                context = activityContext,
                request = createPublicKeyCredentialRequest,
            )
            handlePasskeyRegistrationResult(result)
        } catch (e : CreateCredentialException){
            handleFailure(e)
        }
    }
}

fun handleFailure(e: CreateCredentialException) {
    when (e) {
        is CreatePublicKeyCredentialDomException -> {
            // Handle the passkey DOM errors thrown according to the
            // WebAuthn spec.
            handlePasskeyError(e.domError)
        }
        is CreateCredentialCancellationException -> {
            // The user intentionally canceled the operation and chose not
            // to register the credential.
        }
        is CreateCredentialInterruptedException -> {
            // Retry-able error. Consider retrying the call.
        }
        is CreateCredentialProviderConfigurationException -> {
            // Your app is missing the provider configuration dependency.
            // Most likely, you're missing the
            // "credentials-play-services-auth" module.
        }
        is CreateCredentialUnknownException -> ...
        is CreateCredentialCustomException -> {
            // You have encountered an error from a 3rd-party SDK. If you
            // make the API call with a request object that's a subclass of
            // CreateCustomCredentialRequest using a 3rd-party SDK, then you
            // should check for any custom exception type constants within
            // that SDK to match with e.type. Otherwise, drop or log the
            // exception.
        }
        else -> Log.w(TAG, "Unexpected exception type ${e::class.java.name}")
    }
}

Java

public void createPasskey(String requestJson, boolean preferImmediatelyAvailableCredentials) {
    CreatePublicKeyCredentialRequest createPublicKeyCredentialRequest =
            // `requestJson` contains the request in JSON format. Uses the standard
            // WebAuthn web JSON spec.
            // `preferImmediatelyAvailableCredentials` defines whether you prefer
            // to only use immediately available credentials, not  hybrid credentials,
            // to fulfill this request. This value is false by default.
            new CreatePublicKeyCredentialRequest(
                requestJson, preferImmediatelyAvailableCredentials);

    // Execute CreateCredentialRequest asynchronously to register credentials
    // for a user account. Handle success and failure cases with the result and
    // exceptions, respectively.
    credentialManager.createCredentialAsync(
        // Use an activity-based context to avoid undefined system
        // UI launching behavior
        requireActivity(),
        createPublicKeyCredentialRequest,
        cancellationSignal,
        executor,
        new CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>() {
            @Override
            public void onResult(CreateCredentialResponse result) {
                handleSuccessfulCreatePasskeyResult(result);
            }

            @Override
            public void onError(CreateCredentialException e) {
                if (e instanceof CreatePublicKeyCredentialDomException) {
                    // Handle the passkey DOM errors thrown according to the
                    // WebAuthn spec.
                    handlePasskeyError(((CreatePublicKeyCredentialDomException)e).getDomError());
                } else if (e instanceof CreateCredentialCancellationException) {
                    // The user intentionally canceled the operation and chose not
                    // to register the credential.
                } else if (e instanceof CreateCredentialInterruptedException) {
                    // Retry-able error. Consider retrying the call.
                } else if (e instanceof CreateCredentialProviderConfigurationException) {
                    // Your app is missing the provider configuration dependency.
                    // Most likely, you're missing the
                    // "credentials-play-services-auth" module.
                } else if (e instanceof CreateCredentialUnknownException) {
                } else if (e instanceof CreateCredentialCustomException) {
                    // You have encountered an error from a 3rd-party SDK. If
                    // you make the API call with a request object that's a
                    // subclass of
                    // CreateCustomCredentialRequest using a 3rd-party SDK,
                    // then you should check for any custom exception type
                    // constants within that SDK to match with e.type.
                    // Otherwise, drop or log the exception.
                } else {
                  Log.w(TAG, "Unexpected exception type "
                          + e.getClass().getName());
                }
            }
        }
    );
}

JSON isteğini biçimlendirme

Geçiş anahtarı oluşturduktan sonra bu anahtarı bir kullanıcının hesabıyla ilişkilendirmeniz ve geçiş anahtarının herkese açık anahtarını sunucunuzda saklamanız gerekir. Aşağıdaki kod örneğinde, geçiş anahtarı oluştururken JSON isteğinin nasıl biçimlendirileceği gösterilmektedir.

Uygulamalarınıza sorunsuz kimlik doğrulama getirme hakkındaki bu blog yayınında, geçiş anahtarları oluştururken ve geçiş anahtarlarını kullanarak kimlik doğrularken JSON isteğinizi nasıl biçimlendireceğiniz gösterilmektedir. Ayrıca, şifrelerin neden etkili bir kimlik doğrulama çözümü olmadığı, mevcut biyometrik kimlik bilgilerinden nasıl yararlanılacağı, uygulamanızın sahibi olduğunuz bir web sitesiyle nasıl ilişkilendirileceği, geçiş anahtarlarının nasıl oluşturulacağı ve geçiş anahtarları kullanılarak kimlik doğrulamanın nasıl yapılacağı da açıklanmaktadır.

{
  "challenge": "abc123",
  "rp": {
    "name": "Credential Manager example",
    "id": "credential-manager-test.example.com"
  },
  "user": {
    "id": "def456",
    "name": "helloandroid@gmail.com",
    "displayName": "helloandroid@gmail.com"
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 1800000,
  "attestation": "none",
  "excludeCredentials": [
    {"id": "ghi789", "type": "public-key"},
    {"id": "jkl012", "type": "public-key"}
  ],
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}

authenticatorAttachment için değerleri ayarlama

authenticatorAttachment parametresi yalnızca kimlik bilgisi oluşturulurken ayarlanabilir. platform, cross-platform veya hiç değer belirtmeyebilirsiniz. Çoğu durumda, hiçbir değer önerilmemektedir.

  • platform: Kullanıcının mevcut cihazını kaydetmek veya şifre kullanıcısından oturum açtıktan sonra geçiş anahtarlarına geçmesini istemek için authenticatorAttachment değerini platform olarak ayarlayın.
  • cross-platform: Bu değer genellikle çok faktörlü kimlik bilgilerini kaydederken kullanılır ve geçiş anahtarı bağlamında kullanılmaz.
  • Değer yok: Kullanıcılara tercih ettikleri cihazlarda (ör. hesap ayarlarında) geçiş anahtarı oluşturma esnekliği sunmak için kullanıcı geçiş anahtarı eklemeyi seçtiğinde authenticatorAttachment parametresi belirtilmemelidir. Çoğu durumda, parametreyi belirtilmeden bırakmak en iyi seçenektir.

Yinelenen geçiş anahtarlarının oluşturulmasını engelleme

Aynı geçiş anahtarı sağlayıcısı ile zaten mevcut bir geçiş anahtarı varsa yeni bir geçiş anahtarı oluşturulmasını önlemek için isteğe bağlı excludeCredentials dizisinde kimlik bilgilerini listeleyin.

JSON yanıtını işleme

Aşağıdaki kod snippet'inde, herkese açık anahtar kimlik bilgisi oluşturmaya yönelik örnek bir JSON yanıtı gösterilmektedir. İade edilen herkese açık anahtar kimlik bilgisini nasıl kullanacağınız hakkında daha fazla bilgi edinin.

{
  "id": "KEDetxZcUfinhVi6Za5nZQ",
  "type": "public-key",
  "rawId": "KEDetxZcUfinhVi6Za5nZQ",
  "response": {
    "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoibmhrUVhmRTU5SmI5N1Z5eU5Ka3ZEaVh1Y01Fdmx0ZHV2Y3JEbUdyT0RIWSIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",
    "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViUj5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGRdAAAAAAAAAAAAAAAAAAAAAAAAAAAAEChA3rcWXFH4p4VYumWuZ2WlAQIDJiABIVgg4RqZaJyaC24Pf4tT-8ONIZ5_Elddf3dNotGOx81jj3siWCAWXS6Lz70hvC2g8hwoLllOwlsbYatNkO2uYFO-eJID6A"
  }
}

İstemci verileri JSON'undan kaynağı doğrulama

origin, isteğin geldiği uygulamayı veya web sitesini temsil eder ve kimlik avı saldırılarına karşı koruma sağlamak için geçiş anahtarları tarafından kullanılır. Uygulamanızın sunucusunun, istemci veri kaynağını onaylanmış uygulamaların ve web sitelerinin izin verilenler listesiyle karşılaştırması gerekir. Sunucu, tanınmayan bir kaynaktan gelen bir uygulama veya web sitesinden istek alırsa istek reddedilmelidir.

Web durumunda origin, kimlik bilgisinin oturum açıldığı aynı site kaynağını yansıtır. Örneğin, https://www.example.com:8443/store?category=shoes#athletic URL'si için origin değeri https://www.example.com:8443 olur.

Android uygulamaları için kullanıcı aracısı, origin parametresini çağıran uygulamanın imzasıyla otomatik olarak ayarlar. Geçiş anahtarı API'sinin arayanını doğrulamak için bu imzanın sunucunuzda eşleştiği doğrulanmalıdır. Android origin, APK imzalama sertifikasının SHA-256 karmasından türetilen bir URI'dir. Örneğin:

android:apk-key-hash:<sha256_hash-of-apk-signing-cert>

Bir anahtar deposundaki imzalama sertifikalarının SHA-256 karmaları, aşağıdaki terminal komutunu çalıştırarak bulunabilir:

keytool -list -keystore <path-to-apk-signing-keystore>

SHA-256 karmaları iki nokta işaretiyle ayrılmış onaltılık biçimdedir (91:F7:CB:F9:D6:81…) ve Android origin değerleri base64url olarak kodlanmıştır. Bu Python örneğinde, karma oluşturma biçiminin nasıl uyumlu, iki nokta işaretiyle ayrılmış on altılık biçime dönüştürüleceği gösterilmektedir:

import binascii
import base64
fingerprint = '91:F7:CB:F9:D6:81:53:1B:C7:A5:8F:B8:33:CC:A1:4D:AB:ED:E5:09:C5'
print("android:apk-key-hash:" + base64.urlsafe_b64encode(binascii.a2b_hex(fingerprint.replace(':', ''))).decode('utf8').replace('=', ''))

fingerprint değerini kendi değerinizle değiştirin. Aşağıda bir örnek sonuç verilmiştir:

android:apk-key-hash:kffL-daBUxvHpY-4M8yhTavt5QnFEI2LsexohxrGPYU

Ardından, bu dizeyi sunucunuzda izin verilen bir kaynak olarak eşleştirebilirsiniz. Hata ayıklama ve sürüm sertifikaları gibi birden fazla imzalama sertifikanız veya birden fazla uygulamanız varsa işlemi tekrarlayın ve bu kaynakların tümünü sunucuda geçerli olarak kabul edin.

Kullanıcı şifresini kaydetme

Kullanıcı, uygulamanızda bir kimlik doğrulama akışı için kullanıcı adı ve şifre sağlarsa kullanıcının kimliğini doğrulamak için kullanılabilecek bir kullanıcı kimlik bilgisi kaydedebilirsiniz. Bunu yapmak için bir CreatePasswordRequest nesnesi oluşturun:

Kotlin

fun registerPassword(username: String, password: String) {
    // Initialize a CreatePasswordRequest object.
    val createPasswordRequest =
            CreatePasswordRequest(id = username, password = password)

    // Create credential and handle result.
    coroutineScope.launch {
        try {
            val result =
                credentialManager.createCredential(
                    // Use an activity based context to avoid undefined
                    // system UI launching behavior.
                    activityContext,
                    createPasswordRequest
                  )
            handleRegisterPasswordResult(result)
        } catch (e: CreateCredentialException) {
            handleFailure(e)
        }
    }
}

Java

void registerPassword(String username, String password) {
    // Initialize a CreatePasswordRequest object.
    CreatePasswordRequest createPasswordRequest =
        new CreatePasswordRequest(username, password);

    // Register the username and password.
    credentialManager.createCredentialAsync(
        // Use an activity-based context to avoid undefined
        // system UI launching behavior
        requireActivity(),
        createPasswordRequest,
        cancellationSignal,
        executor,
        new CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>() {
            @Override
            public void onResult(CreateCredentialResponse result) {
                handleResult(result);
            }

            @Override
            public void onError(CreateCredentialException e) {
                handleFailure(e);
            }
        }
    );
}

Kimlik bilgisi kurtarma desteği

Kullanıcının kimlik bilgilerini sakladığı cihaza erişimi yoksa güvenli bir online yedekten kurtarması gerekebilir. Bu kimlik bilgisi kurtarma sürecini nasıl destekleyeceğiniz hakkında daha fazla bilgi edinmek için Google Şifre Yöneticisi'ndeki Geçiş Anahtarları'nın Güvenliği başlıklı blog yayınındaki "Erişimi kurtarma veya yeni cihaz ekleme" bölümünü okuyun.

Şifre anahtarı uç noktalarının iyi bilinen URL'leri olan şifre yönetimi araçları için destek ekleme

Sorunsuz entegrasyon ve gelecekte şifre ve kimlik bilgisi yönetim araçlarıyla uyumluluk için, bilinen URL'ler için geçiş anahtarı uç noktaları desteği eklemenizi öneririz. Bu, uyumlu tarafların geçiş anahtarlarına yönelik desteklerini resmi olarak duyurmaları ve geçiş anahtarı kaydı ile yönetimi için doğrudan bağlantılar sağlamaları için açık bir protokoldür.

  1. https://example.com adresinde bulunan, web sitesi ve Android ile iOS uygulamaları olan bir güvenilir taraf için herkese açık URL https://example.com/.well-known/passkey-endpoints olur.
  2. URL sorgulandığında yanıtta aşağıdaki şema kullanılmalıdır

    {
      "enroll": "https://example.com/account/manage/passkeys/create"
      "manage": "https://example.com/account/manage/passkeys"
    }
    
  3. Bu bağlantının web'de değil, doğrudan uygulamanızda açılmasını istiyorsanız Android uygulama bağlantılarını kullanın.

  4. Daha fazla bilgiyi GitHub'daki geçiş anahtarı uç noktalarının bilinen URL'si açıklamasında bulabilirsiniz.

Geçiş anahtarlarını hangi sağlayıcının oluşturduğunu göstererek kullanıcıların geçiş anahtarlarını yönetmelerine yardımcı olma

Kullanıcıların belirli bir uygulamayla ilişkili birden fazla geçiş anahtarını yönetirken karşılaştığı zorluklardan biri, düzenleme veya silme için doğru geçiş anahtarını tanımlamaktır. Bu soruna yardımcı olmak için uygulamaların ve web sitelerinin, uygulamanızın ayarlar ekranındaki geçiş anahtarları listesinde kimlik bilgisini oluşturan sağlayıcı, oluşturma tarihi ve son kullanım tarihi gibi ek bilgiler eklemesi önerilir.Sağlayıcı bilgileri, ilgili geçiş anahtarıyla ilişkili AAGUID incelenerek elde edilir. AAGUID, geçiş anahtarının kimlik doğrulayıcı verilerinde bulunabilir.

Örneğin, bir kullanıcı Android işletim sistemli bir cihazda Google Şifre Yöneticisi'ni kullanarak geçiş anahtarı oluşturursa RP şuna benzer bir AAGUID alır: "ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4". Güvenen taraf, geçiş anahtarı listesinde geçiş anahtarının Google Şifre Yöneticisi kullanılarak oluşturulduğunu belirtmek için geçiş anahtarına ek açıklama ekleyebilir.

RP'ler, bir AAGUID'yi geçiş anahtarı sağlayıcıyla eşlemek için topluluk kaynaklı bir AAGUID deposunu kullanabilir. Geçiş anahtarı sağlayıcısının adını ve simgesini bulmak için listede AAGUID'yi arayın.

AAGUID entegrasyonu hakkında daha fazla bilgi edinin.

Sık karşılaşılan hataları giderme

Yaygın hata kodları, açıklamaları ve nedenleriyle ilgili bilgiler için Kimlik Bilgisi Yöneticisi sorun giderme kılavuzuna bakın.

Ek kaynaklar

Kimlik Bilgisi Yöneticisi API'si ve şifre anahtarları hakkında daha fazla bilgi edinmek için aşağıdaki kaynakları inceleyin: