अपने उपयोगकर्ता को क्रेडेंशियल मैनेजर से साइन इन करें

Credential Manager एक Jetpack API है. यह एक ही एपीआई में, साइन इन करने के कई तरीकों के साथ काम करता है. जैसे, उपयोगकर्ता नाम और पासवर्ड, पासकी, और फ़ेडरेटेड साइन इन के समाधान (जैसे, 'Google से साइन इन करें'). इससे डेवलपर के लिए इंटिग्रेशन को आसान बनाना होता है.

इसके अलावा, Credential Manager की मदद से, उपयोगकर्ताओं के लिए पुष्टि करने के सभी तरीकों के लिए एक ही साइन इन इंटरफ़ेस उपलब्ध होता है. इससे लोग, ऐप्लिकेशन में आसानी से साइन इन कर पाएंगे. भले ही, उन्होंने साइन इन करने का कोई भी तरीका चुना हो.

इस पेज पर, पासकी के कॉन्सेप्ट और पुष्टि करने से जुड़े समाधानों के लिए क्लाइंट-साइड सहायता को लागू करने का तरीका बताया गया है. इसमें क्रेडेंशियल मैनेजर एपीआई का इस्तेमाल करके, पासकी के बारे में भी बताया गया है. इसके अलावा, अक्सर पूछे जाने वाले सवालों का एक अलग पेज भी है. इस पेज पर, ज़्यादा जानकारी वाले खास सवालों के जवाब दिए गए हैं.

क्रेडेंशियल मैनेजर एपीआई को बेहतर बनाने के लिए, आपके सुझाव, शिकायत या राय की अहम भूमिका होती है. नीचे दिए गए लिंक का इस्तेमाल करके, एपीआई को बेहतर बनाने के लिए सुझाव या समस्याएं शेयर करें:

सुझाव/राय दें या शिकायत करें

पासकी के बारे में जानकारी

पासकी, पासवर्ड के मुकाबले ज़्यादा सुरक्षित और आसान विकल्प हैं. पासकी की मदद से, उपयोगकर्ता ऐप्लिकेशन और वेबसाइटों में साइन इन कर सकते हैं. इसके लिए, उन्हें बायोमेट्रिक सेंसर (जैसे, फ़िंगरप्रिंट या चेहरे की पहचान), पिन या पैटर्न का इस्तेमाल करना होगा. इससे उपयोगकर्ताओं को साइन-इन करने का बेहतरीन अनुभव मिलता है. इससे, उन्हें उपयोगकर्ता नाम या पासवर्ड याद रखने की ज़रूरत नहीं पड़ती.

पासकी, WebAuthn (वेब ऑथेंटिकेशन) पर निर्भर करती हैं. यह एक ऐसा स्टैंडर्ड है जिसे FIDO Alliance और वर्ल्ड वाइड वेब कंसोर्टियम (W3C) ने मिलकर बनाया है. WebAuthn, उपयोगकर्ता की पुष्टि करने के लिए, सार्वजनिक पासकोड क्रिप्टोग्राफ़ी का इस्तेमाल करता है. जिस वेबसाइट या ऐप्लिकेशन में उपयोगकर्ता साइन इन कर रहा है वह सार्वजनिक कुंजी देख सकता है और उसे सेव कर सकता है. हालांकि, वह निजी कुंजी कभी नहीं देख सकता. निजी कुंजी को गुप्त और सुरक्षित रखा जाता है. साथ ही, पासकी यूनीक होती हैं और वेबसाइट या ऐप्लिकेशन से जुड़ी होती हैं. इसलिए, पासकी को फ़िशिंग के ज़रिए हासिल नहीं किया जा सकता. इससे पासकी की सुरक्षा और बेहतर हो जाती है.

क्रेडेंशियल मैनेजर की मदद से लोग पासकी बना सकते हैं और उन्हें Google Password Manager में सेव कर सकते हैं.

क्रेडेंशियल मैनेजर की मदद से, पासकी की मदद से पुष्टि करने के फ़्लो को आसानी से लागू करने का तरीका जानने के लिए, पासकी की मदद से उपयोगकर्ता की पुष्टि करना लेख पढ़ें.

ज़रूरी शर्तें

हार्डवेयर सुरक्षा कुंजियों का इस्तेमाल करता है, तो आपको फ़िलहाल FIDO का इस्तेमाल जारी रखना चाहिए.

क्रेडेंशियल मैनेजर का इस्तेमाल करने के लिए, इस सेक्शन में दिया गया तरीका अपनाएं.

प्लैटफ़ॉर्म का नया वर्शन इस्तेमाल करें

क्रेडेंशियल मैनेजर, Android 4.4 (एपीआई लेवल 19) और इसके बाद के वर्शन पर काम करता है.

अपने ऐप्लिकेशन में डिपेंडेंसी जोड़ना

अपने ऐप्लिकेशन मॉड्यूल की बिल्ड स्क्रिप्ट में ये डिपेंडेंसी जोड़ें:

Kotlin

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

    // 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-beta01")
}

Groovy

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

    // 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-beta01"
}

ProGuard फ़ाइल में क्लास को सुरक्षित रखना

अपने मॉड्यूल की proguard-rules.pro फ़ाइल में, ये निर्देश जोड़ें:

-if class androidx.credentials.CredentialManager
-keep class androidx.credentials.playservices.** {
  *;
}
दिखाते हैं.

अपने ऐप्लिकेशन को छोटा करने, उसे धुंधला करने, और ऑप्टिमाइज़ करने के तरीके के बारे में ज़्यादा जानें.

डिजिटल ऐसेट लिंक के लिए सहायता जोड़ना

अपने Android ऐप्लिकेशन के लिए पासकी की सुविधा चालू करने के लिए, अपने ऐप्लिकेशन को उस वेबसाइट से जोड़ें जिसका मालिकाना हक आपके पास है. इस असोसिएशन का एलान करने के लिए, यह तरीका अपनाएं:

  1. डिजिटल ऐसेट लिंक की JSON फ़ाइल बनाएं. उदाहरण के लिए, यह बताने के लिए कि वेबसाइट https://signin.example.com और पैकेज के नाम com.example वाला Android ऐप्लिकेशन, साइन इन क्रेडेंशियल शेयर कर सकता है, 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 फ़ील्ड, एक या एक से ज़्यादा स्ट्रिंग का कलेक्शन होता है. इन स्ट्रिंग से, एलान की जा रही रिलेशनशिप के बारे में पता चलता है. यह बताने के लिए कि ऐप्लिकेशन और साइटें साइन इन करने के क्रेडेंशियल शेयर करती हैं, संबंधों को delegate_permission/handle_all_urls और delegate_permission/common.get_login_creds के तौर पर बताएं.

    target फ़ील्ड एक ऑब्जेक्ट है, जो उस एसेट के बारे में बताता है जिस पर एलान लागू होता है. इन फ़ील्ड से किसी वेबसाइट की पहचान की जाती है:

    namespace web
    site

    वेबसाइट का यूआरएल, https://domain[:optional_port] फ़ॉर्मैट में; उदाहरण के लिए, https://www.example.com.

    domain एट्रिब्यूट की वैल्यू पूरी तरह क्वालिफ़ाइड होनी चाहिए. साथ ही, एचटीटीपीएस के लिए पोर्ट 443 का इस्तेमाल करते समय, optional_port को हटा दिया जाना चाहिए.

    site टारगेट सिर्फ़ रूट डोमेन हो सकता है: किसी खास सबडायरेक्ट्री के लिए, ऐप्लिकेशन असोसिएशन को सीमित नहीं किया जा सकता. यूआरएल में पाथ शामिल न करें, जैसे कि आखिर में स्लैश.

    सबडोमेन को मैच नहीं माना जाता: इसका मतलब है कि अगर आपने domain को www.example.com के तौर पर बताया है, तो डोमेन www.counter.example.com आपके ऐप्लिकेशन से नहीं जुड़ा है.

    इन फ़ील्ड से किसी Android ऐप्लिकेशन की पहचान की जाती है:

    namespace android_app
    package_name ऐप्लिकेशन के मेनिफ़ेस्ट में बताया गया पैकेज का नाम. उदाहरण के लिए, com.example.android
    sha256_cert_fingerprints आपके ऐप्लिकेशन के साइनिंग सर्टिफ़िकेट के SHA256 फ़िंगरप्रिंट.
  2. साइन इन करने के लिए इस्तेमाल किए जाने वाले डोमेन पर, डिजिटल ऐसेट लिंक JSON फ़ाइल को यहां होस्ट करें:

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

    उदाहरण के लिए, अगर आपका साइन-इन डोमेन signin.example.com है, तो JSON फ़ाइल को https://signin.example.com/.well-known/assetlinks.json पर होस्ट करें.

    डिजिटल ऐसेट लिंक फ़ाइल का MIME टाइप, JSON होना चाहिए. पक्का करें कि सर्वर, रिस्पॉन्स में Content-Type: application/json हेडर भेजे.

  3. पक्का करें कि आपका होस्ट, Google को आपकी डिजिटल ऐसेट लिंक फ़ाइल पाने की अनुमति देता हो. अगर आपके पास robots.txt फ़ाइल है, तो उसमें Googlebot एजेंट को /.well-known/assetlinks.json को फिर से पाने की अनुमति होनी चाहिए. ज़्यादातर साइटें, अपने-आप काम करने वाले किसी भी एजेंट को /.well-known/ पाथ में फ़ाइलें वापस पाने की अनुमति दे सकती हैं. इससे अन्य सेवाएं, उन फ़ाइलों के मेटाडेटा को ऐक्सेस कर सकती हैं:

    User-agent: *
    Allow: /.well-known/
    
  4. <application> के तहत मेनिफ़ेस्ट फ़ाइल में यह लाइन जोड़ें:

    <meta-data android:name="asset_statements" android:resource="@string/asset_statements" />
    
  5. अगर क्रेडेंशियल मैनेजर की मदद से पासवर्ड से साइन इन किया जा रहा है, तो मेनिफ़ेस्ट में डिजिटल ऐसेट लिंक करने के लिए, यह तरीका अपनाएं. अगर सिर्फ़ पासकी का इस्तेमाल किया जा रहा है, तो यह चरण ज़रूरी नहीं है.

    Android ऐप्लिकेशन में असोसिएशन की जानकारी दें. ऐसा ऑब्जेक्ट जोड़ें जिसमें, लोड करने के लिए assetlinks.json फ़ाइलों के बारे में बताया गया हो. आपको स्ट्रिंग में इस्तेमाल किए गए सभी अपस्ट्रॉफ़ और कोटेशन मार्क को एस्केप करना होगा. उदाहरण के लिए:

    <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
    

क्रेडेंशियल मैनेजर को कॉन्फ़िगर करना

CredentialManager ऑब्जेक्ट को कॉन्फ़िगर और शुरू करने के लिए, यहां दिए गए लॉजिक के जैसे लॉजिक जोड़ें:

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)

क्रेडेंशियल फ़ील्ड दिखाएं

Android 14 और उसके बाद के वर्शन में, isCredential एट्रिब्यूट का इस्तेमाल, क्रेडेंशियल फ़ील्ड के बारे में बताने के लिए किया जा सकता है. जैसे, उपयोगकर्ता नाम या पासवर्ड फ़ील्ड. इस एट्रिब्यूट से पता चलता है कि यह व्यू, क्रेडेंशियल फ़ील्ड है. इसका मकसद, क्रेडेंशियल मैनेजर और तीसरे पक्ष के क्रेडेंशियल देने वाले प्रोग्राम के साथ काम करना है. साथ ही, ऑटोमैटिक भरने की सेवाओं को ऑटोमैटिक भरने के बेहतर सुझाव देने में मदद करना है. जब ऐप्लिकेशन, CredentialManager API का इस्तेमाल करता है, तो उस क्रेडेंशियल मैनेजर की बॉटम शीट दिखती है जिसमें उपलब्ध क्रेडेंशियल मौजूद होते हैं. साथ ही, उपयोगकर्ता नाम या पासवर्ड के लिए, ऑटोमैटिक भरने की सुविधा का फ़िल डायलॉग दिखाने की ज़रूरत नहीं होती है. इसी तरह, पासवर्ड के लिए ऑटोमैटिक भरने की सुविधा का'सेव करें' डायलॉग दिखाने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि ऐप्लिकेशन क्रेडेंशियल सेव करने के लिए, क्रेडेंशियल मैनेजर API से अनुरोध करेगा.

isCredential एट्रिब्यूट का इस्तेमाल करने के लिए, उसे काम के व्यू में जोड़ें:

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

अपने उपयोगकर्ता के तौर पर साइन इन करना

उपयोगकर्ता के खाते से जुड़ी सभी पासकी और पासवर्ड के विकल्प वापस पाने के लिए, यह तरीका अपनाएं:

  1. पासवर्ड और पासकी की पुष्टि करने के विकल्पों को शुरू करने के लिए:

    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. साइन-इन करने का अनुरोध करने के लिए, पिछले चरण में मिले विकल्पों का इस्तेमाल करें.

    Kotlin

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

    Java

    GetCredentialRequest getCredRequest = new GetCredentialRequest.Builder()
        .addCredentialOption(getPasswordOption)
        .addCredentialOption(getPublicKeyCredentialOption)
        .build();
  3. साइन-इन फ़्लो लॉन्च करने के लिए:

    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");
        }
    }

पासकी मिलने पर, JSON अनुरोध को फ़ॉर्मैट करने का तरीका यहां बताया गया है:

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

इस उदाहरण में दिखाया गया है कि सार्वजनिक पासकोड का क्रेडेंशियल मिलने के बाद, JSON रिस्पॉन्स कैसा दिख सकता है:

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

क्रेडेंशियल उपलब्ध न होने पर, अपवादों को हैंडल करें

कुछ मामलों में, हो सकता है कि उपयोगकर्ता के पास कोई क्रेडेंशियल उपलब्ध न हो या वह उपलब्ध क्रेडेंशियल का इस्तेमाल करने की सहमति न दे. अगर getCredential() को शुरू किया जाता है और कोई क्रेडेंशियल नहीं मिलता है, तो NoCredentialException दिखाया जाता है. ऐसा होने पर, आपके कोड को NoCredentialException इंस्टेंस हैंडल करने चाहिए.

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 या इसके बाद के वर्शन पर, खाता चुनने वाला टूल दिखाने के दौरान लगने वाले समय को कम किया जा सकता है. इसके लिए, getCredential() को कॉल करने से पहले, prepareGetCredential() तरीके का इस्तेमाल करें.

Kotlin

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

Java

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

prepareGetCredential() तरीका, यूज़र इंटरफ़ेस (यूआई) एलिमेंट को ट्रिगर नहीं करता. यह सिर्फ़ तैयारी करने में आपकी मदद करता है, ताकि बाद में getCredential() एपीआई की मदद से, बाकी क्रेडेंशियल पाने की कार्रवाई (जिसमें यूज़र इंटरफ़ेस शामिल हैं) शुरू की जा सके.

कैश मेमोरी में सेव किया गया डेटा, PrepareGetCredentialResponse ऑब्जेक्ट में दिखता है. अगर मौजूदा क्रेडेंशियल हैं, तो नतीजे कैश मेमोरी में सेव हो जाएंगे. इसके बाद, कैश मेमोरी में सेव किए गए डेटा के साथ खाता चुनने वाला टूल दिखाने के लिए, बाकी बचे getCredential() एपीआई को लॉन्च किया जा सकता है.

रजिस्ट्रेशन फ़्लो

पुष्टि करने के लिए, किसी उपयोगकर्ता को पासकी या पासवर्ड का इस्तेमाल करके रजिस्टर किया जा सकता है.

पासकी बनाना

उपयोगकर्ताओं को पासकी रजिस्टर करने और फिर से पुष्टि करने के लिए इसका इस्तेमाल करने का विकल्प देने के लिए, CreatePublicKeyCredentialRequest ऑब्जेक्ट की मदद से उपयोगकर्ता क्रेडेंशियल रजिस्टर करें.

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 अनुरोध को फ़ॉर्मैट करना

पासकी बनाने के बाद, आपको इसे उपयोगकर्ता के खाते से जोड़ना होगा. साथ ही, पासकी की सार्वजनिक कुंजी को अपने सर्वर पर सेव करना होगा. इस कोड के उदाहरण में, पासकी बनाते समय JSON अनुरोध को फ़ॉर्मैट करने का तरीका बताया गया है.

अपने ऐप्लिकेशन पर आसानी से पुष्टि करने की सुविधा के बारे में बताने वाली यह ब्लॉग पोस्ट. इसमें, पासकी बनाने और पासकी का इस्तेमाल करके पुष्टि करने के दौरान, JSON अनुरोध को फ़ॉर्मैट करने का तरीका बताया गया है. इसमें यह भी बताया गया है कि पासवर्ड, पुष्टि करने का एक असरदार तरीका क्यों नहीं हैं. साथ ही, इसमें मौजूदा बायोमेट्रिक क्रेडेंशियल का फ़ायदा पाने, अपने ऐप्लिकेशन को अपनी मालिकाना हक वाली वेबसाइट से जोड़ने, पासकी बनाने, और पासकी का इस्तेमाल करके पुष्टि करने का तरीका भी बताया गया है.

{
  "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 के लिए वैल्यू सेट करना

authenticatorAttachment पैरामीटर को सिर्फ़ क्रेडेंशियल बनाते समय सेट किया जा सकता है. आपके पास platform, cross-platform या कोई वैल्यू नहीं बताने का विकल्प है. ज़्यादातर मामलों में, वैल्यू सबमिट करने का सुझाव नहीं दिया जाता.

  • platform: उपयोगकर्ता के मौजूदा डिवाइस को रजिस्टर करने या साइन इन करने के बाद, पासवर्ड का इस्तेमाल करने वाले उपयोगकर्ता को पासकी पर अपग्रेड करने के लिए कहने के लिए, authenticatorAttachment को platform पर सेट करें.
  • cross-platform: इस वैल्यू का इस्तेमाल आम तौर पर, कई तरीकों से पुष्टि करने वाले क्रेडेंशियल रजिस्टर करते समय किया जाता है. इसका इस्तेमाल पासकी के संदर्भ में नहीं किया जाता.
  • कोई वैल्यू नहीं: उपयोगकर्ताओं को उनके पसंदीदा डिवाइसों पर (जैसे कि खाता सेटिंग में) पासकी बनाने की सुविधा देने के लिए, जब भी उपयोगकर्ता पासकी जोड़ने का विकल्प चुनता है, तब authenticatorAttachment पैरामीटर नहीं बताना चाहिए. ज़्यादातर मामलों में, पैरामीटर को बिना तय करना सबसे अच्छा विकल्प होता है.

डुप्लीकेट पासकी बनाने से रोकें

अगर पासकी देने वाली सेवा से पहले से कोई पासकी मौजूद है, तो नई पासकी बनाने से रोकने के लिए, वैकल्पिक excludeCredentials कलेक्शन में क्रेडेंशियल आईडी की सूची बनाएं.

JSON रिस्पॉन्स को मैनेज करना

नीचे दिया गया कोड स्निपेट, सार्वजनिक पासकोड क्रेडेंशियल बनाने के लिए JSON रिस्पॉन्स का उदाहरण दिखाता है. सार्वजनिक कुंजी के तौर पर दिखाए गए क्रेडेंशियल को मैनेज करने के तरीके के बारे में ज़्यादा जानें.

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

क्लाइंट डेटा JSON से ऑरिजिन की पुष्टि करना

origin उस ऐप्लिकेशन या वेबसाइट को दिखाता है जिससे अनुरोध भेजा जाता है. पासकी, फ़िशिंग हमलों से सुरक्षा के लिए इसका इस्तेमाल करती हैं. आपके ऐप्लिकेशन के सर्वर को, क्लाइंट के डेटा के ऑरिजिन की जांच करनी होगी. यह जांच, अनुमति पा चुके ऐप्लिकेशन और वेबसाइटों की अनुमति वाली सूची के हिसाब से की जाती है. अगर सर्वर को किसी ऐप्लिकेशन या वेबसाइट से किसी ऐसे ऑरिजिन से अनुरोध मिलता है जिसे पहचाना नहीं जा सका है, तो अनुरोध को अस्वीकार कर दिया जाना चाहिए.

वेब केस में, origin उस साइट के ऑरिजिन को दिखाता है जहां क्रेडेंशियल से साइन इन किया गया था. उदाहरण के लिए, https://www.example.com:8443/store?category=shoes#athletic का यूआरएल दिया गया है , तो origin का यूआरएल https://www.example.com:8443 होगा.

Android ऐप्लिकेशन के लिए, उपयोगकर्ता एजेंट अपने-आप origin को कॉल करने वाले ऐप्लिकेशन के हस्ताक्षर पर सेट कर देता है. पासकी एपीआई के कॉलर की पुष्टि करने के लिए, इस हस्ताक्षर की पुष्टि आपके सर्वर पर एक मैच के तौर पर की जानी चाहिए. Android origin एक यूआरआई है, जिसे APK साइनिंग सर्टिफ़िकेट के SHA-256 हैश से लिया जाता है, जैसे कि:

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

किसी पासकोड सेव करने की जगह में मौजूद, साइनिंग सर्टिफ़िकेट के SHA-256 हैश देखने के लिए, टर्मिनल में यह कमांड चलाएं:

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

SHA-256 हैश, कोलन से अलग किए गए हेक्साडेसिमल फ़ॉर्मैट (91:F7:CB:F9:D6:81…) में होते हैं. साथ ही, Android origin वैल्यू, base64url में एन्कोड की जाती हैं. इस Python उदाहरण में, हैश फ़ॉर्मैट को काम करने वाले, कोलन से अलग किए गए हैक्साडेसिमल फ़ॉर्मैट में बदलने का तरीका बताया गया है:

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 की वैल्यू को अपनी वैल्यू से बदलें. यहां नतीजे का एक उदाहरण दिया गया है:

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

इसके बाद, उस स्ट्रिंग को अपने सर्वर पर अनुमति वाले ऑरिजिन के तौर पर मैच किया जा सकता है. अगर आपके पास एक से ज़्यादा साइनिंग सर्टिफ़िकेट हैं, जैसे कि डीबग करने और रिलीज़ करने के लिए सर्टिफ़िकेट या एक से ज़्यादा ऐप्लिकेशन, तो इस प्रक्रिया को दोहराएं और सर्वर पर उन सभी ऑरिजिन को मान्य के तौर पर स्वीकार करें.

किसी उपयोगकर्ता का पासवर्ड सेव करना

अगर उपयोगकर्ता आपके ऐप्लिकेशन में पुष्टि करने के फ़्लो के लिए उपयोगकर्ता नाम और पासवर्ड डालता है, तो उपयोगकर्ता का क्रेडेंशियल रजिस्टर किया जा सकता है. इसका इस्तेमाल, उपयोगकर्ता की पुष्टि करने के लिए किया जा सकता है. ऐसा करने के लिए, CreatePasswordRequest ऑब्जेक्ट बनाएं:

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);
            }
        }
    );
}

क्रेडेंशियल वापस पाने की सुविधा

अगर किसी उपयोगकर्ता के पास उस डिवाइस का ऐक्सेस नहीं है जिसमें उसने अपने क्रेडेंशियल सेव किए थे, तो उसे सुरक्षित ऑनलाइन बैकअप से क्रेडेंशियल वापस पाने होंगे. क्रेडेंशियल वापस पाने की इस प्रोसेस में मदद करने के तरीके के बारे में ज़्यादा जानने के लिए, इस ब्लॉग पोस्ट में "ऐक्सेस वापस पाना या नए डिवाइस जोड़ना" सेक्शन पढ़ें: Google Password Manager में पासकी की सुरक्षा.

पासकी एंडपॉइंट के जाने-पहचाने यूआरएल वाले पासवर्ड मैनेजमेंट टूल के लिए सहायता जोड़ना

हमारा सुझाव है कि पासकी के एंडपॉइंट के लिए, जाने-पहचाने यूआरएल के साथ काम करने की सुविधा जोड़ें. इससे, पासवर्ड और क्रेडेंशियल मैनेजमेंट टूल के साथ आसानी से इंटिग्रेट किया जा सकेगा और आने वाले समय में इन टूल के साथ काम किया जा सकेगा. यह एक ओपन प्रोटोकॉल है, ताकि पार्टनर, पासकी के साथ काम करने की सुविधा का आधिकारिक तौर पर विज्ञापन कर सकें. साथ ही, पासकी को रजिस्टर करने और मैनेज करने के लिए सीधे लिंक उपलब्ध करा सकें.

  1. https://example.com पर मौजूद किसी भरोसेमंद पक्ष के लिए, जिसकी वेबसाइट के साथ-साथ Android और iOS ऐप्लिकेशन भी हैं, उसका जाना-पहचाना यूआरएल https://example.com/.well-known/passkey-endpoints होगा.
  2. यूआरएल के बारे में क्वेरी करने पर, रिस्पॉन्स में इस स्कीमा का इस्तेमाल किया जाना चाहिए

    {
      "enroll": "https://example.com/account/manage/passkeys/create"
      "manage": "https://example.com/account/manage/passkeys"
    }
    
  3. यह लिंक वेब के बजाय सीधे आपके ऐप्लिकेशन में खुले, इसके लिए Android ऐप्लिकेशन के लिंक का इस्तेमाल करें.

  4. ज़्यादा जानकारी के लिए, GitHub पर पासकी एंडपॉइंट के लोकप्रिय यूआरएल के बारे में जानकारी देने वाले लेख को पढ़ें.

उपयोगकर्ताओं को यह बताकर उनकी पासकी मैनेज करने में मदद करना कि उन्हें किस सेवा देने वाली कंपनी ने बनाया है

किसी ऐप्लिकेशन से जुड़ी कई पासकी मैनेज करते समय, उपयोगकर्ताओं को एक समस्या का सामना करना पड़ता है. यह समस्या, बदलाव करने या मिटाने के लिए सही पासकी की पहचान करने से जुड़ी होती है. इस समस्या में मदद पाने के लिए, हमारा सुझाव है कि ऐप्लिकेशन और वेबसाइटें अन्य जानकारी भी शामिल करें. जैसे, क्रेडेंशियल बनाने वाली कंपनी, उसे बनाने की तारीख, और आपके ऐप्लिकेशन की सेटिंग स्क्रीन पर मौजूद पासकी की सूची में उसे पिछली बार इस्तेमाल किए जाने की तारीख. सेवा देने वाली कंपनी की जानकारी, इससे जुड़ी पासकी से जुड़ी AAGUID की जांच करके ली जाती है. AAGUID, पासकी के पुष्टि करने वाले डेटा के हिस्से के तौर पर मिल सकता है.

उदाहरण के लिए, अगर कोई उपयोगकर्ता Android डिवाइस पर, Google Password Manager का इस्तेमाल करके पासकी बनाता है, तो आरपी को एक AAGUID मिलता है. यह कुछ ऐसा दिखता है: "ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4". भरोसेमंद पक्ष, पासकी की सूची में पासकी के लिए एनोटेशन जोड़ सकता है. इससे यह पता चलता है कि पासकी को Google Password Manager का इस्तेमाल करके बनाया गया था.

किसी AAGUID को पासकी देने वाली कंपनी से मैप करने के लिए, आरपी कम्यूनिटी से मिले AAGUID की रिपॉज़िटरी का इस्तेमाल कर सकते हैं. पासकी की सेवा देने वाली कंपनी का नाम और आइकॉन ढूंढने के लिए, सूची में AAGUID खोजें.

AAGUID इंटिग्रेशन के बारे में ज़्यादा जानें.

सामान्य गड़बड़ियां हल करना

गड़बड़ी के सामान्य कोड, उनके बारे में जानकारी, और उनकी वजहों के बारे में जानने के लिए, Credential Manager से जुड़ी समस्या हल करने की गाइड देखें.

अन्य संसाधन

Credential Manager API और पासकी के बारे में ज़्यादा जानने के लिए, यहां दिए गए रिसॉर्स देखें: