FIDO2 से क्रेडेंशियल मैनेजर पर माइग्रेट करना

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

FIDO2 से क्रेडेंशियल मैनेजर पर माइग्रेट करने की वजहें

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

  • पासकी से जुड़ी सहायता: क्रेडेंशियल मैनेजर पर पासकी काम करती हैं. यह बिना पासवर्ड के पुष्टि करने का एक नया तरीका है. यह पासवर्ड से ज़्यादा सुरक्षित और इस्तेमाल करने में आसान है.
  • साइन इन करने के कई तरीके: Credential Manager में, साइन इन करने के कई तरीके इस्तेमाल किए जा सकते हैं. इनमें पासवर्ड, पासकी, और फ़ेडरेटेड साइन इन के तरीके शामिल हैं. इससे लोगों के लिए आपके ऐप्लिकेशन की पुष्टि करना आसान हो जाता है, भले ही पुष्टि करने का उनका पसंदीदा तरीका कुछ भी हो.
  • तीसरे पक्ष के क्रेडेंशियल उपलब्ध कराने वाली सेवाओं के साथ काम करना: Android 14 और उसके बाद के वर्शन पर, क्रेडेंशियल मैनेजर, तीसरे पक्ष के कई क्रेडेंशियल उपलब्ध कराने वाली सेवाओं के साथ काम करता है. इसका मतलब है कि आपके उपयोगकर्ता, आपके ऐप्लिकेशन में साइन इन करने के लिए, सेवा देने वाली अन्य कंपनियों के अपने मौजूदा क्रेडेंशियल इस्तेमाल कर सकते हैं.
  • एक जैसा उपयोगकर्ता अनुभव: क्रेडेंशियल मैनेजर, सभी ऐप्लिकेशन और साइन-इन करने के तरीकों के लिए पुष्टि करने का एक जैसा उपयोगकर्ता अनुभव देता है. इससे उपयोगकर्ताओं के लिए, आपके ऐप्लिकेशन की पुष्टि करने के फ़्लो को समझना और उसका इस्तेमाल करना आसान हो जाता है.

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

डिपेंडेंसी अपडेट करें

  1. अपने प्रोजेक्ट के create.gradle में Kotlin प्लगिन को वर्शन 1.8.10 या इसके बाद वाले वर्शन पर अपडेट करें.

    plugins {
      //…
        id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
      //…
    }
    
  2. अपने प्रोजेक्ट के build.gradle में, अपनी डिपेंडेंसी अपडेट करें, ताकि क्रेडेंशियल मैनेजर और Play services की पुष्टि करने की सुविधा का इस्तेमाल किया जा सके.

    dependencies {
      // ...
      // Credential Manager:
      implementation 'androidx.credentials:credentials:<latest-version>'
    
      // Play Services Authentication:
      // Optional - needed for credentials support from play services, for devices running
      // Android 13 and below:
      implementation 'androidx.credentials:credentials-play-services-auth:<latest-version>'
      // ...
    }
    
  3. FIDO को शुरू करने की प्रोसेस को क्रेडेंशियल मैनेजर को शुरू करने की प्रोसेस से बदलें. पासकी बनाने और साइन इन करने के तरीकों के लिए इस्तेमाल की जाने वाली क्लास में, यह एलान जोड़ें:

    val credMan = CredentialManager.create(context)
    

पासकी बनाना

इससे पहले कि उपयोगकर्ता इससे साइन इन करे, आपको एक नई पासकी बनानी होगी और उसे उपयोगकर्ता के खाते से जोड़ना होगा. साथ ही, पासकी की सार्वजनिक कुंजी को अपने सर्वर पर सेव करना होगा. रजिस्टर फ़ंक्शन कॉल को अपडेट करके, अपने ऐप्लिकेशन को इस सुविधा के साथ सेट अप करें.

पहला डायग्राम. इस इलस्ट्रेशन में दिखाया गया है कि क्रेडेंशियल मैनेजर का इस्तेमाल करके पासकी बनाने पर, ऐप्लिकेशन और सर्वर के बीच डेटा कैसे शेयर किया जाता है.
  1. पासकी बनाने के दौरान createCredential() तरीके को भेजे गए ज़रूरी पैरामीटर पाने के लिए, अपने registerRequest() सर्वर कॉल में name("residentKey").value("required") जोड़ें, जैसा कि WebAuthn की खास जानकारी में बताया गया है).

    suspend fun registerRequest(sessionId: String ... {
        // ...
        .method("POST", jsonRequestBody {
            name("attestation").value("none")
            name("authenticatorSelection").objectValue {
                name("residentKey").value("required")
            }
        }).build()
        // ...
    }
    
  2. registerRequest() और सभी चाइल्ड फ़ंक्शन के लिए return टाइप को JSONObject पर सेट करें.

    suspend fun registerRequest(sessionId: String): ApiResult<JSONObject> {
        val call = client.newCall(
            Request.Builder()
                .url("$BASE_URL/<your api url>")
                .addHeader("Cookie", formatCookie(sessionId))
                .method("POST", jsonRequestBody {
                    name("attestation").value("none")
                    name("authenticatorSelection").objectValue {
                        name("authenticatorAttachment").value("platform")
                        name("userVerification").value("required")
                        name("residentKey").value("required")
                    }
                }).build()
        )
        val response = call.await()
        return response.result("Error calling the api") {
            parsePublicKeyCredentialCreationOptions(
                body ?: throw ApiException("Empty response from the api call")
            )
        }
    }
    
  3. अपने व्यू से, इंटेंट लॉन्चर और गतिविधि के नतीजे के कॉल मैनेज करने वाले सभी तरीकों को सुरक्षित तरीके से हटाएं.

  4. अब registerRequest(), JSONObject दिखाता है. इसलिए, आपको PendingIntent बनाने की ज़रूरत नहीं है. लौटाए गए इंटेंट को JSONObject से बदलें. Credential Manager API से createCredential() को कॉल करने के लिए, अपने इंटेंट लॉन्चर कॉल को अपडेट करें. createCredential() एपीआई का तरीका कॉल करें.

    suspend fun createPasskey(
        activity: Activity,
        requestResult: JSONObject
        ): CreatePublicKeyCredentialResponse? {
            val request = CreatePublicKeyCredentialRequest(requestResult.toString())
            var response: CreatePublicKeyCredentialResponse? = null
            try {
                response = credMan.createCredential(
                    request as CreateCredentialRequest,
                    activity
                ) as CreatePublicKeyCredentialResponse
            } catch (e: CreateCredentialException) {
    
                showErrorAlert(activity, e)
    
                return null
            }
            return response
        }
    
  5. कॉल पूरा होने के बाद, सर्वर को जवाब वापस भेजें. इस कॉल के लिए अनुरोध और जवाब, FIDO2 के लागू होने की तरह ही है. इसलिए, इसमें कोई बदलाव करने की ज़रूरत नहीं है.

पासकी से पुष्टि करना

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

दूसरी इमेज. क्रेडेंशियल मैनेजर की पासकी से ऑथेंटिकेशन करने का तरीका.
  1. getCredential() अनुरोध पर भेजी जाने वाली ज़रूरी जानकारी पाने के लिए, सर्वर को आपका साइन इन अनुरोध कॉल, FIDO2 लागू करने के तरीके जैसा ही है. किसी बदलाव की ज़रूरत नहीं है.
  2. रजिस्टर अनुरोध कॉल की तरह ही, रिस्पॉन्स JSONObject फ़ॉर्मैट में होता है.

    /**
     * @param sessionId The session ID to be used for the sign-in.
     * @param credentialId The credential ID of this device.
     * @return a JSON object.
     */
    suspend fun signinRequest(): ApiResult<JSONObject> {
        val call = client.newCall(Builder().url(buildString {
            append("$BASE_URL/signinRequest")
        }).method("POST", jsonRequestBody {})
            .build()
        )
        val response = call.await()
        return response.result("Error calling /signinRequest") {
            parsePublicKeyCredentialRequestOptions(
                body ?: throw ApiException("Empty response from /signinRequest")
            )
        }
    }
    
    /**
     * @param sessionId The session ID to be used for the sign-in.
     * @param response The JSONObject for signInResponse.
     * @param credentialId id/rawId.
     * @return A list of all the credentials registered on the server,
     * including the newly-registered one.
     */
    suspend fun signinResponse(
        sessionId: String, response: JSONObject, credentialId: String
        ): ApiResult<Unit> {
    
            val call = client.newCall(
                Builder().url("$BASE_URL/signinResponse")
                    .addHeader("Cookie",formatCookie(sessionId))
                    .method("POST", jsonRequestBody {
                        name("id").value(credentialId)
                        name("type").value(PUBLIC_KEY.toString())
                        name("rawId").value(credentialId)
                        name("response").objectValue {
                            name("clientDataJSON").value(
                                response.getString("clientDataJSON")
                            )
                            name("authenticatorData").value(
                                response.getString("authenticatorData")
                            )
                            name("signature").value(
                                response.getString("signature")
                            )
                            name("userHandle").value(
                                response.getString("userHandle")
                            )
                        }
                    }).build()
            )
            val apiResponse = call.await()
            return apiResponse.result("Error calling /signingResponse") {
            }
        }
    
  3. अपने व्यू से, इंटेंट लॉन्चर और गतिविधि के नतीजे के कॉल को मैनेज करने वाले सभी तरीकों को सुरक्षित तरीके से हटाएं.

  4. अब signInRequest(), JSONObject दिखाता है. इसलिए, आपको PendingIntent बनाने की ज़रूरत नहीं है. दिखाए गए इंटेंट को JSONObject से बदलें और अपने एपीआई के तरीकों से getCredential() को कॉल करें.

    suspend fun getPasskey(
        activity: Activity,
        creationResult: JSONObject
        ): GetCredentialResponse? {
            Toast.makeText(
                activity,
                "Fetching previously stored credentials",
                Toast.LENGTH_SHORT)
                .show()
            var result: GetCredentialResponse? = null
            try {
                val request= GetCredentialRequest(
                    listOf(
                        GetPublicKeyCredentialOption(
                            creationResult.toString(),
                            null
                        ),
                        GetPasswordOption()
                    )
                )
                result = credMan.getCredential(activity, request)
                if (result.credential is PublicKeyCredential) {
                    val publicKeycredential = result.credential as PublicKeyCredential
                    Log.i("TAG", "Passkey ${publicKeycredential.authenticationResponseJson}")
                    return result
                }
            } catch (e: Exception) {
                showErrorAlert(activity, e)
            }
            return result
        }
    
  5. कॉल पूरा होने के बाद, उपयोगकर्ता की पुष्टि करने के लिए रिस्पॉन्स को सर्वर पर भेजें. इस एपीआई कॉल के लिए अनुरोध और जवाब पैरामीटर, FIDO2 के लागू होने से पहले के जैसे ही हैं. इसलिए, इसमें कोई बदलाव करने की ज़रूरत नहीं है.

अन्य संसाधन