2025 की चौथी तिमाही का अपडेट: अपने Android ऐप्लिकेशन में Credential Manager API का इस्तेमाल करके, पुष्टि करने की प्रोसेस को आसान बनाने का तरीका जानें

1. शुरू करने से पहले

पुष्टि करने के पारंपरिक तरीकों से, सुरक्षा और इस्तेमाल से जुड़ी कई समस्याएं आती हैं.

पासवर्ड का इस्तेमाल बड़े पैमाने पर किया जाता है, लेकिन...

  • आसानी से भूल जाने वाला
  • उपयोगकर्ताओं को मज़बूत पासवर्ड बनाने के बारे में जानकारी होनी चाहिए.
  • इसे हैकर आसानी से फ़िश कर सकते हैं, इकट्ठा कर सकते हैं, और फिर से चला सकते हैं.

Android ने Credential Manager API बनाया है. इससे साइन इन करने की प्रोसेस को आसान बनाया जा सकता है. साथ ही, पासकी का इस्तेमाल करके, सुरक्षा से जुड़े जोखिमों को कम किया जा सकता है. पासवर्ड के बिना पुष्टि करने के लिए, पासकी इंडस्ट्री का अगला स्टैंडर्ड है.

Credential Manager, पासकी के साथ-साथ पासवर्ड और 'Google से साइन इन करें' जैसे पुष्टि करने के पारंपरिक तरीकों का इस्तेमाल करने की सुविधा देता है.

उपयोगकर्ता पासकी बना सकेंगे और उन्हें Google Password Manager में सेव कर सकेंगे. इससे, वे पासकी उन सभी Android डिवाइसों पर सिंक हो जाएंगी जिन पर उपयोगकर्ता ने साइन इन किया है. पासकी का इस्तेमाल करके साइन इन करने से पहले, उसे बनाना होगा. साथ ही, उसे किसी उपयोगकर्ता खाते से जोड़ना होगा. इसके अलावा, उसकी सार्वजनिक पासकी को किसी सर्वर पर सेव करना होगा.

इस कोडलैब में, Credential Manager API का इस्तेमाल करके पासकी और पासवर्ड से साइन अप करने का तरीका जानें. साथ ही, आने वाले समय में पुष्टि करने के लिए इनका इस्तेमाल करने का तरीका जानें. इसमें दो फ़्लो शामिल हैं:

  • साइन अप करना : पासकी और पासवर्ड का इस्तेमाल करके.
  • साइन इन करना : पासकी और सेव किए गए पासवर्ड का इस्तेमाल करके.

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

  • Android Studio में ऐप्लिकेशन चलाने के तरीके के बारे में बुनियादी जानकारी.
  • Android ऐप्लिकेशन में पुष्टि करने की प्रोसेस की बुनियादी जानकारी.
  • पासकी के बारे में बुनियादी जानकारी.

आपको क्या सीखने को मिलेगा

  • पासकी बनाने का तरीका.
  • पासवर्ड मैनेजर में पासवर्ड सेव करने का तरीका.
  • पासकी या सेव किए गए पासवर्ड की मदद से, उपयोगकर्ताओं की पुष्टि करने का तरीका.

आपको किन चीज़ों की ज़रूरत होगी

डिवाइसों के इनमें से किसी एक कॉम्बिनेशन का इस्तेमाल किया जा सकता है:

  • Android 9 या इसके बाद के वर्शन पर चलने वाला Android डिवाइस (पासकी के लिए) और Android 4.4 या इसके बाद के वर्शन पर चलने वाला Android डिवाइस(Credential Manager API के ज़रिए पासवर्ड की पुष्टि करने के लिए).
  • डिवाइस में बायोमेट्रिक सेंसर होना चाहिए.
  • पक्का करें कि आपने स्क्रीन लॉक (बायोमेट्रिक या कोई अन्य तरीका) रजिस्टर किया हो.
  • Kotlin प्लगिन का वर्शन : 1.8.10

2. सेट अप करें

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

प्रोजेक्ट में बताए गए debug.keystore का इस्तेमाल करके, डीबग और रिलीज़ वैरिएंट बनाएं. इससे, मॉक सर्वर पर पैकेज के नाम और SHA के डिजिटल ऐसेट लिंक की पुष्टि की जा सकेगी. (build.gradle में मौजूद सैंपल ऐप्लिकेशन के लिए, यह पहले से किया जा रहा है).

  1. अपने लैपटॉप पर, credman_codelab ब्रांच से इस रेपो को क्लोन करें: https://github.com/android/identity-samples/tree/credman_codelab
git clone -b credman_codelab https://github.com/android/identity-samples.git
  1. CredentialManager मॉड्यूल पर जाएं और Android Studio में प्रोजेक्ट खोलें.

इससे ऐप्लिकेशन की शुरुआती स्थिति का पता चलता है

ऐप्लिकेशन की शुरुआती स्थिति कैसे काम करती है, यह देखने के लिए यह तरीका अपनाएं:

  1. ऐप्लिकेशन लॉन्च करें.
  2. आपको साइन अप और साइन इन करने के बटन के साथ मुख्य स्क्रीन दिखती है. ये बटन अभी कुछ नहीं करते, लेकिन हम आने वाले सेक्शन में इनकी सुविधा चालू करेंगे.

7a6fe80f4cf877a8.jpeg

3. पासकी का इस्तेमाल करके साइन अप करने की सुविधा जोड़ना

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

अब आपको बायोमेट्रिक/स्क्रीन लॉक का इस्तेमाल करके, पासकी बनानी होगी और उपयोगकर्ता के क्रेडेंशियल रजिस्टर करने होंगे.

पासकी से साइन अप करना

CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignUpScreen.kt में मौजूद कोड, "username" टेक्स्ट फ़ील्ड और पासकी से साइन अप करने के लिए बटन को तय करता है.

1f4c50daa2551f1.jpeg

View Model में इस्तेमाल करने के लिए, createCredential() लैम्डा तय करना

क्रेडेंशियल मैनेजर ऑब्जेक्ट के लिए, Activity को पास करना ज़रूरी है. यह Activity, स्क्रीन से जुड़ा होता है. हालांकि, क्रेडेंशियल मैनेजर की कार्रवाइयां आम तौर पर व्यू मॉडल में ट्रिगर होती हैं. इसलिए, व्यू मॉडल में गतिविधियों को रेफ़र करने का सुझाव नहीं दिया जाता. इसलिए, हम क्रेडेंशियल मैनेजर के फ़ंक्शन को एक अलग फ़ाइल CredentialManagerUtil.kt में तय करते हैं और उन्हें सही स्क्रीन में रेफ़रंस करते हैं. इसके बाद, ये फ़ंक्शन लैम्डा फ़ंक्शन के ज़रिए, अपने व्यू मॉडल को कॉलबैक के तौर पर पास करते हैं.

CredentialManagerUtil.kt में मौजूद createCredential() फ़ंक्शन में TODO टिप्पणी ढूंढें और CredentialManager.create() फ़ंक्शन को कॉल करें:

CredentialManagerUtil.kt

suspend fun createCredential(
    activity: Activity,
    request: CreateCredentialRequest
): CreateCredentialResponse {
    TODO("Create a CredentialManager object and call createCredential() with a CreateCredentialRequest")
    val credentialManager = CredentialManager.create(activity)
    return credentialManager.createCredential(activity, request)
}

चैलेंज और अन्य JSON जवाब को createPasskey() कॉल में पास करें

पासकी बनाने से पहले, आपको सर्वर से ज़रूरी जानकारी का अनुरोध करना होगा. यह जानकारी, createCredential() कॉल के दौरान Credential Manager API को भेजी जाएगी.

आपके प्रोजेक्ट की ऐसेट में पहले से ही एक मॉक रिस्पॉन्स मौजूद है. इसे RegFromServer.txt कहा जाता है. यह इस कोडलैब में ज़रूरी पैरामीटर दिखाता है.

  • अपने ऐप्लिकेशन में, SignUpViewModel.kt पर जाएं. SignUpViewModel.kt तरीके को ढूंढें. यहां आपको पासकी बनाने और उपयोगकर्ता को ऐक्सेस देने के लिए लॉजिक लिखना होगा.signUpWithPasskeys आपको यह तरीका, उसी क्लास में मिलेगा.
  • TODO टिप्पणी ब्लॉक को create a CreatePublicKeyCredentialRequest() पर ढूंढें और इसे इस कोड से बदलें:

SignUpViewModel.kt

TODO("Create a CreatePublicKeyCredentialRequest() with necessary registration json from server")
    val request = CreatePublicKeyCredentialRequest(
        jsonProvider.fetchRegistrationJson()
            .replace("<userId>", getEncodedUserId())
            .replace("<userName>", _username.value)
            .replace("<userDisplayName>", _username.value)
            .replace("<challenge>", getEncodedChallenge())
    )

jsonProvider.fetchRegistrationJsonFromServer() तरीका, ऐसेट से सर्वर PublicKeyCredentialCreationOptions के JSON रिस्पॉन्स को पढ़ता है. साथ ही, पासकी बनाते समय पास किए जाने वाले रजिस्ट्रेशन JSON को दिखाता है. हम प्लेसहोल्डर की कुछ वैल्यू को अपने ऐप्लिकेशन से मिली उपयोगकर्ता की एंट्री और कुछ मॉक फ़ील्ड से बदल देते हैं:

  • यह JSON अधूरा है और इसमें चार फ़ील्ड हैं जिन्हें बदलने की ज़रूरत है.
  • UserId यूनीक होना चाहिए, ताकि उपयोगकर्ता एक से ज़्यादा पासकी बना सके (अगर ज़रूरी हो). जनरेट की गई userId वैल्यू को <userId> से बदलें.
  • <challenge> भी यूनीक होना चाहिए, इसलिए आपको एक रैंडम यूनीक चैलेंज जनरेट करना होगा. यह तरीका आपके कोड में पहले से मौजूद है.

असली सर्वर PublicKeyCredentialCreationOptions से मिले जवाब में ज़्यादा विकल्प हो सकते हैं. इनमें से कुछ फ़ील्ड का उदाहरण यहां दिया गया है:

{
  "challenge": String,
  "rp": {
    "name": String,
    "id": String
  },
  "user": {
    "id": String,
    "name": String,
    "displayName": String
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 1800000,
  "attestation": "none",
  "excludeCredentials": [],
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}

यहां दी गई टेबल में, PublicKeyCredentialCreationOptions ऑब्जेक्ट में मौजूद कुछ अहम पैरामीटर के बारे में बताया गया है:

पैरामीटर

जानकारी

challenge

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

user.id

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

user.name

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

user.displayName

यह फ़ील्ड, खाते का वैकल्पिक नाम है. यह नाम, उपयोगकर्ता के लिए ज़्यादा आसान होता है.

rp.id

रिलाइंग पार्टी इकाई, आपके आवेदन की जानकारी से मेल खाती है. इसमें ये एट्रिब्यूट शामिल हैं:

  • name (ज़रूरी है): आपके ऐप्लिकेशन का नाम
  • ID (ज़रूरी नहीं): यह डोमेन या सबडोमेन से मेल खाता है. अगर यह मौजूद नहीं है, तो मौजूदा डोमेन का इस्तेमाल किया जाता है.
  • icon (ज़रूरी नहीं).

pubKeyCredParams

अनुमति वाले एल्गोरिदम और कुंजी के टाइप की सूची. इस सूची में कम से कम एक एलिमेंट होना चाहिए.

excludeCredentials

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

authenticatorSelection.authenticatorAttachment

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

residentKey

पासकी बनाने के लिए, वैल्यू required को चुनें.

क्रेडेंशियल बनाना

  1. CreatePublicKeyCredentialRequest() बनाने के बाद, आपको बनाए गए अनुरोध के साथ createCredential() कॉल करना होगा.

SignUpViewModel.kt

try {
   TODO("Call createCredential() with createPublicKeyCredentialRequest")
   createCredential(request)
   TODO("Complete the registration process after sending public key credential to your server and let the user in")

} catch (e: CreateCredentialException) {
   handlePasskeyFailure(e)
}

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

1ea8ace66135de1e.png

  1. आखिर में, आपको रजिस्ट्रेशन की प्रोसेस पूरी करनी होगी. ऐप्लिकेशन, सर्वर को सार्वजनिक कुंजी क्रेडेंशियल भेजता है. सर्वर, इसे मौजूदा उपयोगकर्ता के लिए रजिस्टर करता है.

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

signUpWithPasskeys() तरीके में जाकर, काम की टिप्पणी ढूंढें और उसे इस कोड से बदलें:

SignUpViewModel.kt

try {
    createCredential(request)
    TODO("Complete the registration process after sending public key credential to your server and let the user in")
registerResponse()
    DataProvider.setSignedInThroughPasskeys(true)
    _navigationEvent.emit(NavigationEvent.NavigateToHome(signedInWithPasskeys = true))
} catch (e: CreateCredentialException) {
   handlePasskeyFailure(e)
}
  • registerResponse(), true दिखाता है. इसका मतलब है कि मॉक सर्वर ने सार्वजनिक पासकोड को बाद में इस्तेमाल करने के लिए सेव कर लिया है.
  • setSignedInThroughPasskeys फ़्लैग को true पर सेट करें.
  • लॉग इन करने के बाद, उपयोगकर्ता को होम स्क्रीन पर रीडायरेक्ट करें.

असल PublicKeyCredential में ज़्यादा फ़ील्ड हो सकते हैं. इन फ़ील्ड का उदाहरण यहां दिया गया है:

{
  "id": String,
  "rawId": String,
  "type": "public-key",
  "response": {
    "clientDataJSON": String,
    "attestationObject": String,
  }
}

यहां दी गई टेबल में, PublicKeyCredential ऑब्जेक्ट में मौजूद कुछ अहम पैरामीटर के बारे में बताया गया है:

पैरामीटर

जानकारी

id

यह बनाई गई पासकी का Base64URL कोड में बदला गया आईडी होता है. इस आईडी से ब्राउज़र को यह तय करने में मदद मिलती है कि पुष्टि करने के दौरान, डिवाइस में मिलती-जुलती पासकी मौजूद है या नहीं. यह वैल्यू, बैकएंड पर मौजूद डेटाबेस में सेव होनी चाहिए.

rawId

ArrayBuffer ऑब्जेक्ट, क्रेडेंशियल आईडी का वर्शन होता है.

response.clientDataJSON

ArrayBuffer ऑब्जेक्ट में क्लाइंट का एन्कोड किया गया डेटा होता है.

response.attestationObject

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

ऐप्लिकेशन चलाएं. इसके बाद, पासकी से साइन अप करें बटन पर क्लिक करके, पासकी बनाई जा सकती है.

4. क्रेडेंशियल प्रोवाइडर में पासवर्ड सेव करना

इस ऐप्लिकेशन में, साइन अप स्क्रीन पर, उपयोगकर्ता नाम और पासवर्ड के साथ साइन अप करने की सुविधा पहले से लागू है. इसे सिर्फ़ दिखाने के लिए लागू किया गया है.

उपयोगकर्ता के पासवर्ड क्रेडेंशियल को पासवर्ड सेवा देने वाली कंपनी के साथ सेव करने के लिए, आपको CreatePasswordRequest लागू करना होगा. इससे createCredential() को पासवर्ड सेव करने के लिए पास किया जा सकेगा.

  • signUpWithPassword() तरीका ढूंढें और TODO को createPassword कॉल से बदलें:

SignUpViewModel.kt

TODO("CreatePasswordRequest with entered username and password")
    val passwordRequest = CreatePasswordRequest(_username.value, _password.value)

  • इसके बाद, पासवर्ड बनाने के अनुरोध के साथ क्रेडेंशियल बनाएं. साथ ही, उपयोगकर्ता के पासवर्ड क्रेडेंशियल को उसके पासवर्ड देने वाली कंपनी के साथ सेव करें. इसके बाद, उपयोगकर्ता को लॉग इन करें. हम इस फ़्लो में होने वाली गड़बड़ियों को ज़्यादा सामान्य तरीके से ठीक करते हैं. TODO की जगह यह कोड डालें:

SignUpViewModel.kt

TODO("Create credential with created password request and log the user in")
    try {
        createCredential(passwordRequest)
        simulateServerDelayAndLogIn()
    } catch (e: Exception) {
        val errorMessage = "Exception Message : " + e.message
        Log.e("Auth", errorMessage)
        _passwordCreationError.value = errorMessage
        _isLoading.value = false
    }

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

5. पासकी या पासवर्ड की मदद से पुष्टि करने की सुविधा जोड़ना

अब आपके पास, अपने ऐप्लिकेशन में सुरक्षित तरीके से पुष्टि करने का विकल्प है.

76e81460b26f9798.png

View Model में इस्तेमाल करने के लिए, getCredential() लैंबडा तय करना

पहले की तरह, हम क्रेडेंशियल मैनेजर के getCredential() को अलग फ़ाइल CredentialManagerUtil.kt में कॉल करेंगे. इससे, सही स्क्रीन में रेफ़रंस दिया जा सकेगा और lambda फ़ंक्शन के ज़रिए व्यू मॉडल को कॉलबैक के तौर पर पास किया जा सकेगा.

CredentialManagerUtil.kt में मौजूद getCredential() फ़ंक्शन में TODO टिप्पणी ढूंढें और CredentialManager.get() फ़ंक्शन को कॉल करें:

suspend fun getCredential(
    activity: Activity,
    request: GetCredentialRequest
): GetCredentialResponse {
    TODO("Create a CredentialManager object and call getCredential() with a GetCredentialRequest")
    val credentialManager = CredentialManager.create(activity)
    return credentialManager.getCredential(activity, request)
}

getPasskey() कॉल को पास करने के लिए, चुनौती और अन्य विकल्प पाएं

उपयोगकर्ता से पुष्टि करने के लिए कहने से पहले, आपको सर्वर से अनुरोध पैरामीटर मांगने होंगे. इनमें चुनौती भी शामिल है, ताकि WebAuthn JSON में पास किया जा सके.

आपके पास पहले से ही आपकी ऐसेट (AuthFromServer.txt) में मॉक रिस्पॉन्स है. यह कोडलैब में ऐसे पैरामीटर दिखाता है.

  • अपने ऐप्लिकेशन में, SignInViewModel.kt पर जाएं. इसके बाद, signInWithSavedCredentials तरीका ढूंढें. यहां आपको सेव की गई पासकी या पासवर्ड की मदद से पुष्टि करने का लॉजिक लिखना होगा. साथ ही, उपयोगकर्ता को साइन इन करने की अनुमति देनी होगी:
  • GetPublicKeyCredentialOption() बनाएं. इसमें क्रेडेंशियल की सेवा देने वाली कंपनी से क्रेडेंशियल पाने के लिए ज़रूरी पैरामीटर शामिल करें.

SignInViewModel.kt

TODO("Create a GetPublicKeyCredentialOption() with necessary authentication json from server")
    val getPublicKeyCredentialOption =
        GetPublicKeyCredentialOption(jsonProvider.fetchAuthJson(), null)

fetchAuthJsonFromServer() तरीका, ऐसेट से पुष्टि करने वाले JSON रिस्पॉन्स को पढ़ता है. साथ ही, इस उपयोगकर्ता खाते से जुड़ी सभी पासकी वापस पाने के लिए, पुष्टि करने वाला JSON दिखाता है.

GetPublicKeyCredentialOption() का दूसरा पैरामीटर clientDataHash है. यह एक हैश है. इसका इस्तेमाल, भरोसा करने वाली पार्टी की पहचान की पुष्टि करने के लिए किया जाता है. इस वैल्यू को सिर्फ़ तब सेट करें, जब आपने GetCredentialRequest.origin को सेट किया हो. सैंपल ऐप्लिकेशन के लिए, इसे null पर सेट किया गया है.

ध्यान दें : इस कोडलैब का सर्वर, एक ऐसा JSON दिखाता है जो PublicKeyCredentialRequestOptions डिक्शनरी के जितना हो सके उतना मिलता-जुलता हो. यह डिक्शनरी, API के getCredential() कॉल को पास की जाती है. नीचे दिए गए कोड स्निपेट में, कुछ उदाहरण विकल्प शामिल हैं. ये विकल्प आपको असली जवाब में मिल सकते हैं:

{
  "challenge": String,
  "rpId": String,
  "userVerification": "",
  "timeout": 1800000
}

यहां दी गई टेबल में, PublicKeyCredentialRequestOptions ऑब्जेक्ट में मौजूद कुछ अहम पैरामीटर के बारे में बताया गया है:

पैरामीटर

जानकारी

challenge

ArrayBuffer ऑब्जेक्ट में सर्वर से जनरेट किया गया चैलेंज. रिप्ले अटैक को रोकने के लिए, इसकी ज़रूरत होती है. जवाब में एक ही चैलेंज को दो बार स्वीकार न करें. इसे सीएसआरएफ़ टोकन माना जाता है.

rpId

आरपी आईडी एक डोमेन होता है. कोई वेबसाइट, अपना डोमेन या रजिस्टर किया जा सकने वाला सफ़िक्स तय कर सकती है. यह वैल्यू, पासकी बनाते समय इस्तेमाल किए गए rp.id पैरामीटर से मेल खानी चाहिए.

  • इसके बाद, आपको एक PasswordOption() ऑब्जेक्ट बनाना होगा, ताकि इस उपयोगकर्ता खाते के लिए, Credential Manager API के ज़रिए पासवर्ड सेव करने की सुविधा देने वाली कंपनी में सेव किए गए सभी पासवर्ड वापस पाए जा सकें. getSavedCredentials() तरीके में, TODO ढूंढें और उसे इससे बदलें:

SigninViewModel.kt

TODO("Create a PasswordOption to retrieve all the associated user's password")

val getPasswordOption = GetPasswordOption()

इन सभी को मिलाकर एक GetCredentialRequest बनाओ.

SigninViewModel.kt

TODO("Combine requests into a GetCredentialRequest")
    val request = GetCredentialRequest(
        listOf(
            getPublicKeyCredentialOption,
            getPasswordOption
        )
    )

क्रेडेंशियल पाएं

इसके बाद, आपको ऊपर दिए गए सभी विकल्पों के साथ getCredential() अनुरोध को कॉल करना होगा, ताकि उससे जुड़े क्रेडेंशियल वापस पाए जा सकें:

SignInViewModel.kt

try {
    TODO("Call getCredential() with required credential options")
    val result = getCredential(request)

    val data = when (result.credential) {
        is PublicKeyCredential -> {
            val cred = result.credential as PublicKeyCredential
            DataProvider.setSignedInThroughPasskeys(true)
            "Passkey: ${cred.authenticationResponseJson}"
        }

        is PasswordCredential -> {
            val cred = result.credential as PasswordCredential
            DataProvider.setSignedInThroughPasskeys(false)
            "Got Password - User:${cred.id} Password: ${cred.password}"
        }

        is CustomCredential -> {
            //If you are also using any external sign-in libraries, parse them here with the utility functions provided.
            null
        }

        else -> null
    }

    TODO("Complete the authentication process after validating the public key credential to your server and let the user in.")
    } catch (e: Exception) {
        Log.e("Auth", "getCredential failed with exception: " + e.message.toString())
        _signInError.value =
            "An error occurred while authenticating: " + e.message.toString()
    } finally {
        _isLoading.value = false
    }
  • getCredential() को ज़रूरी जानकारी भेजी जाती है. यह क्रेडेंशियल के विकल्पों की सूची और गतिविधि के कॉन्टेक्स्ट को लेता है, ताकि उस कॉन्टेक्स्ट में बॉटमशीट में विकल्पों को रेंडर किया जा सके.
  • अनुरोध पूरा होने के बाद, आपको अपनी स्क्रीन पर एक बॉटमशीट दिखेगी. इसमें, लिंक किए गए खाते के लिए बनाए गए सभी क्रेडेंशियल की सूची होगी.
  • अब उपयोगकर्ता, चुने गए क्रेडेंशियल की पुष्टि करने के लिए, बायोमेट्रिक्स या स्क्रीन लॉक वगैरह का इस्तेमाल करके अपनी पहचान की पुष्टि कर सकते हैं.
  • अगर चुना गया क्रेडेंशियल PublicKeyCredential है, तो setSignedInThroughPasskeys फ़्लैग को true के तौर पर सेट करें. ऐसा न होने पर, इसे false पर सेट करें.

यहां दिए गए कोड स्निपेट में, PublicKeyCredential ऑब्जेक्ट का एक उदाहरण शामिल है:

{
  "id": String
  "rawId": String
  "type": "public-key",
  "response": {
    "clientDataJSON": String
    "authenticatorData": String
    "signature": String
    "userHandle": String
  }
}

यहां दी गई टेबल में PublicKeyCredential ऑब्जेक्ट के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें अहम पैरामीटर शामिल हैं:

पैरामीटर

जानकारी

id

पुष्टि किए गए पासकी क्रेडेंशियल का Base64URL कोड में बदला गया आईडी.

rawId

ArrayBuffer ऑब्जेक्ट, क्रेडेंशियल आईडी का वर्शन होता है.

response.clientDataJSON

क्लाइंट के डेटा का ArrayBuffer ऑब्जेक्ट. इस फ़ील्ड में ऐसी जानकारी होती है जिसकी पुष्टि आरपी सर्वर को करनी होती है. जैसे, चुनौती और ऑरिजिन.

response.authenticatorData

पुष्टि करने वाले व्यक्ति के डेटा का ArrayBuffer ऑब्जेक्ट. इस फ़ील्ड में आरपी आईडी जैसी जानकारी होती है.

response.signature

हस्ताक्षर का ArrayBuffer ऑब्जेक्ट. यह वैल्यू, क्रेडेंशियल का मुख्य हिस्सा होती है. इसकी पुष्टि सर्वर पर की जानी चाहिए.

response.userHandle

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

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

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

signInWithSavedCredentials() तरीके में, काम की टिप्पणी ढूंढें और उसे इस कोड से बदलें:

SignInViewModel.kt

TODO("Complete the authentication process after validating the public key credential to your server and let the user in.")
    if (data != null) {
        sendSignInResponseToServer()
        _navigationEvent.emit(NavigationEvent.NavigateToHome(signedInWithPasskeys = DataProvider.isSignedInThroughPasskeys()))
    }
  • sendSigninResponseToServer(), सही वैल्यू दिखाता है. इसका मतलब है कि (मॉक) सर्वर ने सार्वजनिक पासकोड की पुष्टि कर ली है, ताकि इसका इस्तेमाल आने वाले समय में किया जा सके.
  • लॉग इन करने के बाद, उपयोगकर्ता को होम स्क्रीन पर रीडायरेक्ट करें.

ऐप्लिकेशन चलाएं और साइन इन करें > पासकी/सेव किए गए पासवर्ड से साइन इन करें पर जाएं. इसके बाद,सेव किए गए क्रेडेंशियल का इस्तेमाल करके साइन इन करें.

इसे आज़माएं

आपने अपने Android ऐप्लिकेशन में, Credential Manager API का इस्तेमाल करके पासकी बनाने, Credential Manager में पासवर्ड सेव करने, और पासकी या सेव किए गए पासवर्ड से पुष्टि करने की सुविधा लागू की हो.

6. बधाई हो!

आपने यह कोडलैब पूरा कर लिया है! अगर आपको फ़ाइनल समाधान देखना है, तो https://github.com/android/identity-samples/tree/main/CredentialManager पर जाएं

अगर आपका कोई सवाल है, तो उसे StackOverflow पर passkey टैग के साथ पूछें.

ज़्यादा जानें