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, kullanıcılar için oturum açma işlemini birleştirir. kimlik doğrulama yöntemleri genelinde arayüz oluşturmak, böylece kullanıcılar için istedikleri yöntem ne olursa olsun uygulamalarda oturum açmalarını sağlar.

Bu sayfada, geçiş anahtarı kavramı ve geçiş anahtarı kullanımıyla ilgili adımlar açıklanmaktadır. geçiş anahtarları da dahil olmak üzere kimlik doğrulama çözümleri için Kimlik Bilgisi Yöneticisi API'si. Ayrıca şu bilgilerin yer aldığı ayrı bir SSS sayfası da vardır: daha ayrıntılı ve spesifik soruların yanıtlarını bulabilirsiniz.

Geri bildiriminiz, Credential Manager API'yi iyileştirmenin önemli bir parçasıdır. 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ı Kullanıcılar uygulamalarda ve web sitelerinde biyometrik sensör (ör. parmak izi veya yüz tanıma), PIN veya desen. Bu sayede, oturum açma deneyimini kullanarak kullanıcı adlarını hatırlama veya şifreler.

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. Oluşturulan web sitesi veya oturum açan kullanıcı ortak anahtarı görebilir ve depolayabilir, ancak gizli anahtarı hiçbir zaman tuşuna basın. Özel anahtar gizli ve güvende tutulur. Anahtar kelimeler benzersiz olduğundan geçiş anahtarları kimlik avına karşı korunmadığından daha fazla güvenlik sağlar.

Kimlik Bilgisi Yöneticisi, kullanıcıların geçiş anahtarları oluşturmasına ve bunları Google Şifre Yöneticisi.

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.

En son platform sürümlerinden birini kullan

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

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

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ı nasıl küçülteceğiniz, karartacağınız ve optimize edeceğiniz hakkında daha fazla bilgi edinin.

Dijital Varlık Bağlantıları için destek ekleme

Android uygulamanızda geçiş anahtarı desteğini etkinleştirmek için uygulamanızı bir en iyi uygulamaları paylaşacağız. 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 sitesi ve paketi içeren bir Android uygulaması com.example adı oturum açma kimlik bilgilerini paylaşabilir, şu adında bir dosya oluşturur: Şu içeriğe sahip assetlinks.json:

    [
      {
        "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ı, ilişkin başka bir açıklamadır. Uygulamaların ve sitelerin aynı oturum açma bilgilerini paylaştığını beyan etmek kimlik bilgileri, ilişkileri delegate_permission/handle_all_urls ve delegate_permission/common.get_login_creds.

    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 (biçimdeki) https://domain[:optional_port]; şunun için: örnek, 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ı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 SHA256 parmak izleri sertifika imzalama başlıklı makaleye bakın.
  2. Digital Assets Link JSON dosyasını şu konumda barındırmalıdır: oturum açma alan adı:

    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. Bir robots.txt dosyanız varsa bu dosya, Googlebot aracısının şunları yapmasına izin vermelidir: /.well-known/assetlinks.json öğesini getir. Çoğu site diğer otomatik aracı sayesinde /.well-known/ yolundaki dosyaları alır hizmetleri bu dosyalardaki meta verilere erişebilir:

    User-agent: *
    Allow: /.well-known/
    
  4. <application> altındaki manifest dosyasına 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'te dijital öğe bağlamayı yapılandırmak için bu adımı uygulayın. Bu adım yalnızca geçiş anahtarı kullanıyorsanız gereklidir.

    Android uygulamasında ilişkilendirmeyi beyan edin. Yüklenecek assetlinks.json dosyalarını belirten bir nesne ekleyin. Kesme işaretlerinin ve dizede kullandığınız tırnak işaretlerinin arasında yer alır. Ö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 şuna benzer bir mantık ekleyin: şu:

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 şu amaçlarla kullanılabilir: kullanıcı adı veya şifre alanları gibi kimlik bilgisi alanlarını belirtmeyin. Bu özellik bu görünümün, birlikte çalışmak üzere tasarlanmış bir kimlik bilgisi alanı olduğunu gösterir Otomatik doldurmaya yardımcı olurken Kimlik Bilgisi Yöneticisi ve üçüncü taraf kimlik bilgisi sağlayıcıları hizmetleri daha iyi otomatik doldurma önerileri sağlar. Uygulama, kimlik bilgisini kullandığında Manager API'sinde, kullanılabilir kimlik bilgilerini içeren Kimlik Bilgisi Yöneticisi alt sayfası ve sayfa için otomatik doldurmanın doldur iletişim kutusunu göstermeye gerek kalmadan kullanıcı adınız veya şifreniz. Benzer şekilde, otomatik doldurmanın uygulama, Credential Manager API'yi isteyeceğinden şifreler için iletişim kutusunu kaydet seçeneğini tıklayın.

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ızın oturumu açın

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. Önceki adımda aldığınız seçenekleri kullanarak oturum açma isteği gönderin.

    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, aşağıdaki durumlarda JSON isteğinin nasıl biçimlendirileceği gösterilmektedir bir şifre anahtarı alırsınız:

{
  "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 bilgileri olmayabilir veya kullanılabilir bir Yeterlilik Belgesi kullanımına izin vermemelidir. getCredential() çağrılırsa ve kimlik bilgileri bulunamazsa NoCredentialException döndürülür. Bu durumda, kodunuzun NoCredentialException öğesini işlemesi gerekir. sağlar.

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 hesabı gösterirken gecikmeyi azaltabilirsiniz. çağırmadan önce prepareGetCredential() yöntemini kullanarak seçici getCredential().

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. Sadece paydaşlarla hazırlık çalışmalarını siz gerçekleştireceksiniz; böylece kalan getCredential() API üzerinden get-credential işlemi (kullanıcı arayüzleri içerir).

Önbelleğe alınan veriler bir PrepareGetCredentialResponse nesnesi olarak döndürülür. Eğer mevcut kimlik bilgileri varsa sonuçlar önbelleğe alınır ve böylece daha sonra hesabı etkinleştirmek için kalan getCredential() API'sini başlatın seçicinin önbelleğine alınmış verileri içermesi gerekir.

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ı kaydedip bu geçiş anahtarını yeniden kimlik doğrulama için kullanma seçeneği sunmak isterseniz CreatePublicKeyCredentialRequest nesnesini kullanarak kullanıcı kimlik bilgisini kaydetme.

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 bunu bir kullanıcının hesabıyla ilişkilendirmeniz gerekir. geçiş anahtarının ortak anahtarını sunucunuzda saklamanız gerekir. Aşağıdaki kod örneğinde Geçiş anahtarı oluşturduğunuzda JSON isteğini biçimlendirme.

Uygulamalarınızda sorunsuz kimlik doğrulama olanağı sunmayla ilgili bu blog yayınında gösterilmektedir geçiş anahtarı oluşturduğunuzda ve diğer işlemler için JSON isteğinizi geçiş anahtarı kullanarak kimlik doğrulaması yapar. Ayrıca, şifrelerin neden etkili bir yöntem kimlik doğrulama çözümü, mevcut biyometrik kimlik bilgilerinden nasıl yararlanılır, sahip olduğunuz bir web sitesiyle ilişkilendirme, geçiş anahtarı oluşturma ve geçiş anahtarı kullanın.

{
  "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 gerekir. platform veya cross-platform belirtebilirsiniz ya da değer belirtmemeyi tercih edebilirsiniz. Çoğu durumda değer önerilmez.

  • platform: Kullanıcının mevcut cihazını kaydettirmek veya şifre istemek için kullanıcının oturum açtıktan sonra geçiş anahtarına yükseltmesi için authenticatorAttachment - platform.
  • cross-platform: Bu değer, çok öğeli etkinliği kaydederken yaygın olarak 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, en iyi yöntem parametreyi belirtilmeden bırakmaktır seçeneğini belirleyin.

Yinelenen geçiş anahtarı oluşturulmasını önleme

Önlem almak için isteğe bağlı excludeCredentials dizisindeki kimlik bilgisi kimliklerini listeleyin. aynı geçiş anahtarına sahip bir geçiş anahtarı varsa yeni bir geçiş anahtarı oluşturma için kullanılır.

JSON yanıtını işleme

Aşağıdaki kod snippet'i, herkese açık anahtar kimlik bilgisi. Döndürülen ortak anahtarın nasıl ele alınacağı hakkında daha fazla bilgi edinin. kimlik bilgisi.

{
  "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, bir isteğinin geldiği adrestir 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 aldığında, isteğin reddedilmesi gerekir.

Web söz konusu olduğunda origin, aynı site kaynağını yansıtır. Kimlik bilgisiyle oturum açıldı. Örneğin, https://www.example.com:8443/store?category=shoes#athletic , origin https://www.example.com:8443.

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, türetilmiş bir URI'dır APK imzalama sertifikasının SHA-256 karmasından kaldırın. Ö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ırın:

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

SHA-256 karmaları, iki nokta üst üste işaretiyle ayrılmış onaltılık biçimdedir (91:F7:CB:F9:D6:81…) ve Android origin değerleri base64url olarak kodlandı. 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. Bir örnekle açıklayalım sonuç:

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

Daha sonra 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ının ş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. Öğrenmek için Bu kimlik bilgisi kurtarma işleminin nasıl destekleneceği hakkında daha fazla bilgi için "Erişimi kurtarma veya yeni cihaz ekleme" başlıklı şu blog yayınında: Google Şifre Yöneticisi'ndeki geçiş anahtarları

Geçiş anahtarı uç noktaları iyi bilinen URL'lerle şifre yönetimi araçları için destek eklendi

Sorunsuz entegrasyon ve şifre ile kimlik bilgisi yönetim araçlarıyla gelecekteki 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 içinde, web sitesine sahip bir bağlı taraf için Android ve iOS uygulamaları, iyi bilinen URL https://example.com/.well-known/passkey-endpoints.
  2. URL sorgulandığında yanıt aşağıdaki şemayı kullanmalıdır

    {
      "enroll": "https://example.com/account/manage/passkeys/create"
      "manage": "https://example.com/account/manage/passkeys"
    }
    
  3. Bu bağlantının web yerine doğrudan uygulamanızda açılması için şunu kullanın: Android uygulama bağlantıları.

  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önetmesine yardımcı olun

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. Şu konularda yardımcı olmak için: varsa, uygulamaların ve web sitelerinin ek Kimlik bilgisini oluşturan sağlayıcı, oluşturma tarihi ve uygulamanızın ayarlar ekranındaki geçiş anahtarları listesinde son kullanılan tarih.Sağlayıcı bilgi, ilişkili AAGUID incelenerek elde edilir giriş yapın. AAGUID, şifre anahtarının parçası olarak bulunabilir. kimlik doğrulayıcı verileri.

Ö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, AAGUID'yi geçiş anahtarı sağlayıcıyla eşlemek için topluluk kaynaklı bir topluluk AAGUID'lerin depolandığı yerdir. AAGUID'yi listesinde geçiş anahtarı sağlayıcısının adını ve simgesini bulabilirsiniz.

AAGUID entegrasyonu hakkında daha fazla bilgi edinin.

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

Aşağıdaki tabloda, sık karşılaşılan bazı hata kodları ve açıklamaları gösterilmektedir ve nedenleri hakkında bazı bilgiler verir:

Hata kodu ve açıklaması Neden
"Başlangıçta Oturum Açma Hatası:" 16: Arayanın erişim süresi geçici olarak engellendi oturum açma istemine neden oldu.

Geliştirme sırasında bu 24 saatlik bekleme süresiyle karşılaşırsanız Google Play Hizmetleri'nin uygulama depolama alanını temizleyerek sıfırlayabilirsiniz.

Alternatif olarak, bu bekleme süresini bir test cihazında veya emülatörde devre dışı bırakmak için Arama uygulamasına gidip aşağıdaki kodu girin: *#*#66382723#*#*. Telefon uygulaması tüm girişleri temizleyip kapanabilir ancak onay mesajı gösterilmez.

"Başlangıç"ta Oturum Açma Hatası: 8: Bilinmeyen dahili hata.
  1. Cihaz, Google Hesabı ile düzgün bir şekilde ayarlanmamış.
  2. Geçiş anahtarı JSON'u yanlış oluşturuluyor.
CreatePublicKeyCredentialDomException: Gelen istek doğrulanamıyor Uygulamanın paket kimliği sunucunuza kaydedilmemiş. Bunu doğrula .
CreateCredentialUnknownException: Şifre kayıt sırasında şifre bulundu tek dokunuşla hata yanıtı 16: Kullanıcı olduğundan beri şifre kaydetme işlemi atlanıyor muhtemelen Android Otomatik Doldurma özelliği ile isteniyor Bu hata yalnızca Android 13 ve önceki sürümlerde, otomatik doldurma sağlayıcısı Google ise ortaya çıkar. Bu durumda, kullanıcılara Otomatik Doldurma'dan bir kaydetme istemi gösterilir ve şifre Google Şifre Yöneticisi'ne kaydedilir. Google ile otomatik doldurma özelliği kullanılarak kaydedilen kimlik bilgilerinin Kimlik Bilgisi Yöneticisi API'si ile iki yönlü olarak paylaşılır. Bu nedenle, bu hata güvenli bir şekilde yoksayılabilir.

Ek kaynaklar

Credential Manager API ve geçiş anahtarları hakkında daha fazla bilgi edinmek için şu kaynakları inceleyin: