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

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

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

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

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

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

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

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

पासकी, WebAuthn (वेब ऑथेंटिकेशन) पर निर्भर करती हैं. यह एक स्टैंडर्ड है, जिसे FIDO एलायंस और वर्ल्ड वाइड वेब कंसोर्टियम (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 एट्रिब्यूट का इस्तेमाल, क्रेडेंशियल फ़ील्ड के बारे में बताने के लिए किया जा सकता है. जैसे, उपयोगकर्ता नाम या पासवर्ड फ़ील्ड. इस एट्रिब्यूट से पता चलता है कि यह व्यू, क्रेडेंशियल फ़ील्ड है. इसका मकसद, क्रेडेंशियल मैनेजर और तीसरे पक्ष के क्रेडेंशियल देने वाले प्रोग्राम के साथ काम करना है. साथ ही, ऑटोमैटिक भरने की सेवाओं को ऑटोमैटिक भरने के बेहतर सुझाव देने में मदद करना है. जब ऐप्लिकेशन, क्रेडेंशियल मैनेजर एपीआई का इस्तेमाल करता है, तो उपलब्ध क्रेडेंशियल के साथ क्रेडेंशियल मैनेजर की सबसे नीचे मौजूद शीट दिखती है. इसके बाद, उपयोगकर्ता नाम या पासवर्ड के लिए, अपने-आप भरने की सुविधा का डायलॉग बॉक्स दिखाने की ज़रूरत नहीं होती. इसी तरह, पासवर्ड के लिए ऑटोमैटिक भरने की सुविधा का'सेव करें' डायलॉग दिखाने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि ऐप्लिकेशन क्रेडेंशियल सेव करने के लिए, क्रेडेंशियल मैनेजर 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 और पासकी के बारे में ज़्यादा जानने के लिए, यहां दिए गए रिसॉर्स देखें: