ক্রেডেনশিয়াল ম্যানেজার দিয়ে আপনার ব্যবহারকারীকে সাইন ইন করুন

ক্রেডেনশিয়াল ম্যানেজার হল একটি Jetpack API যা একাধিক সাইন-ইন পদ্ধতি সমর্থন করে, যেমন ব্যবহারকারীর নাম এবং পাসওয়ার্ড, পাসকি এবং ফেডারেটেড সাইন-ইন সমাধানগুলি (যেমন Google-এর সাথে সাইন-ইন) একক API-এ, এইভাবে বিকাশকারীদের জন্য ইন্টিগ্রেশন সহজতর করে৷

অধিকন্তু, ব্যবহারকারীদের জন্য, শংসাপত্র ম্যানেজার প্রমাণীকরণ পদ্ধতি জুড়ে সাইন-ইন ইন্টারফেসকে একীভূত করে, ব্যবহারকারীরা যে পদ্ধতি বেছে নিন তা নির্বিশেষে অ্যাপগুলিতে সাইন-ইন করাকে আরও পরিষ্কার এবং সহজ করে তোলে।

এই পৃষ্ঠাটি পাসকিগুলির ধারণা এবং ক্রেডেনশিয়াল ম্যানেজার API ব্যবহার করে পাসকি সহ প্রমাণীকরণ সমাধানগুলির জন্য ক্লায়েন্ট-সাইড সমর্থন বাস্তবায়নের পদক্ষেপগুলি ব্যাখ্যা করে। এছাড়াও একটি পৃথক FAQ পৃষ্ঠা রয়েছে যা আরও বিস্তারিত, নির্দিষ্ট প্রশ্নের উত্তর প্রদান করে।

আপনার প্রতিক্রিয়া ক্রেডেনশিয়াল ম্যানেজার API উন্নত করার একটি গুরুত্বপূর্ণ অংশ। নিম্নলিখিত লিঙ্কটি ব্যবহার করে API উন্নত করার জন্য আপনি খুঁজে পান এমন কোনো সমস্যা বা ধারণা শেয়ার করুন:

মতামত দিন

পাসকি সম্পর্কে

পাসকিগুলি পাসওয়ার্ডগুলির জন্য একটি নিরাপদ এবং সহজ প্রতিস্থাপন। পাসকি দিয়ে, ব্যবহারকারীরা বায়োমেট্রিক সেন্সর (যেমন আঙ্গুলের ছাপ বা মুখের স্বীকৃতি), পিন বা প্যাটার্ন ব্যবহার করে অ্যাপ এবং ওয়েবসাইটে সাইন ইন করতে পারেন। এটি একটি বিরামহীন সাইন-ইন অভিজ্ঞতা প্রদান করে, যা আপনার ব্যবহারকারীদের ব্যবহারকারীর নাম বা পাসওয়ার্ড মনে রাখার থেকে মুক্ত করে৷

পাসকিগুলি WebAuthn (ওয়েব প্রমাণীকরণ) এর উপর নির্ভর করে, এটি FIDO অ্যালায়েন্স এবং ওয়ার্ল্ড ওয়াইড ওয়েব কনসোর্টিয়াম (W3C) দ্বারা যৌথভাবে তৈরি একটি স্ট্যান্ডার্ড। WebAuthn ব্যবহারকারীকে প্রমাণীকরণ করতে পাবলিক-কী ক্রিপ্টোগ্রাফি ব্যবহার করে। ব্যবহারকারী যে ওয়েবসাইট বা অ্যাপে সাইন ইন করছেন তা সর্বজনীন কী দেখতে এবং সংরক্ষণ করতে পারে, কিন্তু ব্যক্তিগত কী কখনই নয়। ব্যক্তিগত কী গোপন এবং নিরাপদ রাখা হয়. এবং চাবিটি অনন্য এবং ওয়েবসাইট বা অ্যাপের সাথে আবদ্ধ হওয়ায়, পাসকিগুলি ফিশযোগ্য নয়, আরও নিরাপত্তা যোগ করে৷

ক্রেডেনশিয়াল ম্যানেজার ব্যবহারকারীদের পাসকি তৈরি করতে এবং Google পাসওয়ার্ড ম্যানেজারে সংরক্ষণ করতে দেয়।

ক্রেডেনশিয়াল ম্যানেজারের সাথে কীভাবে নির্বিঘ্ন পাসকি প্রমাণীকরণ ফ্লো বাস্তবায়ন করা যায় তার নির্দেশনার জন্য পাসকি সহ ব্যবহারকারীর প্রমাণীকরণ পড়ুন।

পূর্বশর্ত

ক্রেডেনশিয়াল ম্যানেজার ব্যবহার করতে, এই বিভাগে পদক্ষেপগুলি সম্পূর্ণ করুন৷

একটি সাম্প্রতিক প্ল্যাটফর্ম সংস্করণ ব্যবহার করুন

ক্রেডেনশিয়াল ম্যানেজার Android 4.4 (API স্তর 19) এবং উচ্চতর সংস্করণে সমর্থিত।

আপনার অ্যাপে নির্ভরতা যোগ করুন

আপনার অ্যাপ মডিউলের বিল্ড স্ক্রিপ্টে নিম্নলিখিত নির্ভরতা যোগ করুন:

কোটলিন

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

    // optional - needed for credentials support from play services, for devices running
    // Android 13 and below.
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0-alpha05")
}

গ্রোভি

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

    // optional - needed for credentials support from play services, for devices running
    // Android 13 and below.
    implementation "androidx.credentials:credentials-play-services-auth:1.5.0-alpha05"
}

ProGuard ফাইলে ক্লাস সংরক্ষণ করুন

আপনার মডিউলের proguard-rules.pro ফাইলে, নিম্নলিখিত নির্দেশাবলী যোগ করুন:

-if class androidx.credentials.CredentialManager
-keep class androidx.credentials.playservices.** {
  *;
}

কীভাবে আপনার অ্যাপটি সঙ্কুচিত, অস্পষ্ট এবং অপ্টিমাইজ করবেন সে সম্পর্কে আরও জানুন।

ডিজিটাল সম্পদ লিঙ্কের জন্য সমর্থন যোগ করুন

আপনার অ্যান্ড্রয়েড অ্যাপের জন্য পাসকি সমর্থন সক্ষম করতে, আপনার অ্যাপের মালিকানাধীন ওয়েবসাইটের সাথে আপনার অ্যাপটিকে সংযুক্ত করুন। আপনি নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করে এই সমিতি ঘোষণা করতে পারেন:

  1. একটি ডিজিটাল সম্পদ লিঙ্ক JSON ফাইল তৈরি করুন। উদাহরণস্বরূপ, https://signin.example.com ওয়েবসাইট এবং com.example প্যাকেজ নামের একটি অ্যান্ড্রয়েড অ্যাপ সাইন-ইন শংসাপত্র শেয়ার করতে পারে তা ঘোষণা করতে, নিম্নলিখিত বিষয়বস্তু সহ 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

    ওয়েবসাইটের URL, https:// domain [: optional_port ] ; উদাহরণস্বরূপ, https://www.example.com

    domain সম্পূর্ণরূপে-যোগ্য হতে হবে। এবং HTTPS-এর জন্য পোর্ট 443 ব্যবহার করার সময় optional_port বাদ দিতে হবে।

    একটি site টার্গেট শুধুমাত্র একটি রুট ডোমেন হতে পারে: আপনি একটি নির্দিষ্ট সাবডিরেক্টরিতে একটি অ্যাপ অ্যাসোসিয়েশন সীমাবদ্ধ করতে পারবেন না। URL-এ একটি পথ অন্তর্ভুক্ত করবেন না, যেমন একটি ট্রেলিং স্ল্যাশ৷

    সাবডোমেনগুলিকে মেলে বলে মনে করা হয় না: অর্থাৎ, আপনি যদি 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. আপনি যদি ক্রেডেনশিয়াল ম্যানেজারের মাধ্যমে পাসওয়ার্ড সাইন-ইন ব্যবহার করেন, তাহলে ম্যানিফেস্টে ডিজিটাল সম্পদ লিঙ্কিং কনফিগার করতে এই ধাপটি অনুসরণ করুন। আপনি যদি শুধুমাত্র পাসকি ব্যবহার করেন তবে এই পদক্ষেপের প্রয়োজন নেই।

    অ্যান্ড্রয়েড অ্যাপে অ্যাসোসিয়েশন ঘোষণা করুন। লোড করার জন্য 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 অবজেক্ট কনফিগার এবং আরম্ভ করতে, নিম্নলিখিত অনুরূপ যুক্তি যোগ করুন:

কোটলিন

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
val credentialManager = CredentialManager.create(context)

জাভা

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
CredentialManager credentialManager = CredentialManager.create(context)

শংসাপত্র ক্ষেত্র নির্দেশ করুন

Android 14 এবং উচ্চতর সংস্করণে, isCredential বৈশিষ্ট্যটি শংসাপত্রের ক্ষেত্রগুলি যেমন ব্যবহারকারীর নাম বা পাসওয়ার্ড ক্ষেত্রগুলি নির্দেশ করতে ব্যবহার করা যেতে পারে। এই বৈশিষ্ট্যটি নির্দেশ করে যে এই দৃশ্যটি একটি শংসাপত্রের ক্ষেত্র যা ক্রেডেনশিয়াল ম্যানেজার এবং তৃতীয় পক্ষের শংসাপত্র প্রদানকারীদের সাথে কাজ করার উদ্দেশ্যে, অটোফিল পরিষেবাগুলিকে আরও ভাল অটোফিল পরামর্শ প্রদান করতে সহায়তা করে৷ যখন অ্যাপটি ক্রেডেনশিয়াল ম্যানেজার API ব্যবহার করে, তখন উপলব্ধ শংসাপত্র সহ ক্রেডেনশিয়াল ম্যানেজার নীচের শীটটি প্রদর্শিত হয় এবং ব্যবহারকারীর নাম বা পাসওয়ার্ডের জন্য স্বয়ংক্রিয়ভাবে পূরণ করার ডায়ালগ দেখানোর আর কোন প্রয়োজন নেই৷ একইভাবে, পাসওয়ার্ডের জন্য অটোফিলের সেভ ডায়ালগ দেখানোর কোনো প্রয়োজন নেই, কারণ অ্যাপটি ক্রেডেনশিয়াল ম্যানেজার API-কে শংসাপত্রগুলি সংরক্ষণ করার জন্য অনুরোধ করবে।

isCredential অ্যাট্রিবিউট ব্যবহার করতে, এটি প্রাসঙ্গিক ভিউতে যোগ করুন:

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

আপনার ব্যবহারকারী সাইন ইন করুন

ব্যবহারকারীর অ্যাকাউন্টের সাথে যুক্ত সমস্ত পাসকি এবং পাসওয়ার্ড বিকল্পগুলি পুনরুদ্ধার করতে, এই পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. পাসওয়ার্ড এবং পাসকি প্রমাণীকরণ বিকল্পগুলি শুরু করুন:

    কোটলিন

    // 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
    )

    জাভা

    // 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. সাইন-ইন অনুরোধ তৈরি করতে পূর্ববর্তী ধাপ থেকে পুনরুদ্ধার করা বিকল্পগুলি ব্যবহার করুন।

    কোটলিন

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

    জাভা

    GetCredentialRequest getCredRequest = new GetCredentialRequest.Builder()
        .addCredentialOption(getPasswordOption)
        .addCredentialOption(getPublicKeyCredentialOption)
        .build();
  3. সাইন-ইন প্রবাহ চালু করুন:

    কোটলিন

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

    জাভা

    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 দৃষ্টান্তগুলি পরিচালনা করা উচিত।

কোটলিন

try {
  val credential = credentialManager.getCredential(credentialRequest)
} catch (e: NoCredentialException) {
  Log.e("CredentialManager", "No credential available", e)
}

জাভা

try {
  Credential credential = credentialManager.getCredential(credentialRequest);
} catch (NoCredentialException e) {
  Log.e("CredentialManager", "No credential available", e);
}

Android 14 বা উচ্চতর সংস্করণে, getCredential() কল করার আগে prepareGetCredential() পদ্ধতি ব্যবহার করে অ্যাকাউন্ট নির্বাচককে দেখানোর সময় আপনি লেটেন্সি কমাতে পারেন।

কোটলিন

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

জাভা

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

prepareGetCredential() পদ্ধতি UI উপাদানগুলিকে আহ্বান করে না। এটি শুধুমাত্র আপনাকে প্রস্তুতির কাজ সম্পাদন করতে সাহায্য করে যাতে আপনি পরবর্তীতে getCredential() API-এর মাধ্যমে অবশিষ্ট get-credential অপারেশন (যার মধ্যে UIs জড়িত) চালু করতে পারেন।

ক্যাশ করা ডেটা একটি PrepareGetCredentialResponse অবজেক্টে ফেরত দেওয়া হয়। যদি বিদ্যমান শংসাপত্রগুলি থাকে, ফলাফলগুলি ক্যাশে করা হবে এবং আপনি পরে ক্যাশ করা ডেটা সহ অ্যাকাউন্ট নির্বাচককে আনতে অবশিষ্ট getCredential() API চালু করতে পারেন৷

নিবন্ধন প্রবাহ

আপনি পাসকি বা পাসওয়ার্ড ব্যবহার করে প্রমাণীকরণের জন্য একজন ব্যবহারকারীকে নিবন্ধন করতে পারেন।

একটি পাসকি তৈরি করুন

ব্যবহারকারীদের একটি পাসকি তালিকাভুক্ত করার এবং এটিকে পুনরায় প্রমাণীকরণের জন্য ব্যবহার করার পছন্দ দিতে, একটি CreatePublicKeyCredentialRequest অবজেক্ট ব্যবহার করে একটি ব্যবহারকারীর শংসাপত্র নিবন্ধন করুন৷

কোটলিন

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

জাভা

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 সংযুক্তি প্যারামিটার শুধুমাত্র শংসাপত্র তৈরির সময় সেট করা যেতে পারে। আপনি platform , cross-platform , বা কোনো মান উল্লেখ করতে পারেন। বেশিরভাগ ক্ষেত্রে, কোন মান সুপারিশ করা হয় না।

  • platform : ব্যবহারকারীর বর্তমান ডিভাইস নিবন্ধন করতে বা সাইন-ইন করার পরে পাসকিতে আপগ্রেড করার জন্য একটি পাসওয়ার্ড ব্যবহারকারীকে অনুরোধ করতে, platform authenticatorAttachment সেট করুন।
  • 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 এর একটি URL দেওয়া হয়েছে, origin হল https://www.example.com:8443

অ্যান্ড্রয়েড অ্যাপ্লিকেশানগুলির জন্য, ব্যবহারকারী এজেন্ট স্বয়ংক্রিয়ভাবে কলিং অ্যাপের স্বাক্ষরে origin সেট করে৷ পাসকি API-এর কলকারীকে যাচাই করতে এই স্বাক্ষরটি আপনার সার্ভারে একটি মিল হিসাবে যাচাই করা উচিত। Android origin হল একটি URI যা 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 মানগুলি বেস64url-এনকোডেড৷ এই পাইথন উদাহরণটি দেখায় কিভাবে হ্যাশ ফরম্যাটটিকে একটি সামঞ্জস্যপূর্ণ, কোলন-বিচ্ছিন্ন হেক্সাডেসিমেল ফর্ম্যাটে রূপান্তর করতে হয়:

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 অবজেক্ট তৈরি করুন:

কোটলিন

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

জাভা

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 পাসওয়ার্ড ম্যানেজারে পাসকিগুলির নিরাপত্তা

পাসকি এন্ডপয়েন্ট সুপরিচিত URL এর সাথে পাসওয়ার্ড পরিচালনার সরঞ্জামগুলির জন্য সমর্থন যোগ করুন

পাসওয়ার্ড এবং শংসাপত্র পরিচালনার সরঞ্জামগুলির সাথে বিরামহীন একীকরণ এবং ভবিষ্যতের সামঞ্জস্যের জন্য, আমরা পাসকি এন্ডপয়েন্টগুলি সুপরিচিত URLগুলির জন্য সমর্থন যোগ করার পরামর্শ দিই৷ এটি সারিবদ্ধ দলগুলির জন্য একটি উন্মুক্ত প্রোটোকল যা আনুষ্ঠানিকভাবে পাসকিগুলির জন্য তাদের সমর্থনের বিজ্ঞাপন দেয় এবং পাসকি তালিকাভুক্তি এবং পরিচালনার জন্য সরাসরি লিঙ্ক প্রদান করে।

  1. https://example.com এ একটি নির্ভরশীল পক্ষের জন্য, যার একটি ওয়েবসাইট এবং Android এবং iOS অ্যাপ রয়েছে, সুপরিচিত URLটি হবে https://example.com/.well-known/passkey-endpoints
  2. যখন URL জিজ্ঞাসা করা হয়, তখন প্রতিক্রিয়া নিম্নলিখিত স্কিমা ব্যবহার করা উচিত

    {
      "enroll": "https://example.com/account/manage/passkeys/create"
      "manage": "https://example.com/account/manage/passkeys"
    }
    
  3. এই লিঙ্কটি ওয়েবের পরিবর্তে সরাসরি আপনার অ্যাপে খুলতে, Android অ্যাপ লিঙ্কগুলি ব্যবহার করুন৷

  4. GitHub-এ পাসকি এন্ডপয়েন্টের সুপরিচিত URL ব্যাখ্যাকারীতে আরও বিশদ বিবরণ পাওয়া যাবে।

কোন প্রদানকারী তাদের তৈরি করেছে তা দেখিয়ে ব্যবহারকারীদের তাদের পাসকি পরিচালনা করতে সহায়তা করুন

একটি প্রদত্ত অ্যাপের সাথে যুক্ত একাধিক পাসকি পরিচালনা করার সময় ব্যবহারকারীদের একটি চ্যালেঞ্জ হচ্ছে সম্পাদনা বা মুছে ফেলার জন্য সঠিক পাসকি সনাক্ত করা। এই সমস্যাটিতে সহায়তা করার জন্য, এটি সুপারিশ করা হয় যে অ্যাপ এবং ওয়েবসাইটগুলি আপনার অ্যাপের সেটিংস স্ক্রিনে একটি পাসকি তালিকায় প্রমাণপত্রাদি তৈরিকারী প্রদানকারী, তৈরির তারিখ এবং সর্বশেষ-ব্যবহৃত তারিখের মতো অতিরিক্ত তথ্য অন্তর্ভুক্ত করুন৷ প্রদানকারীর তথ্য পরীক্ষা করে প্রাপ্ত করা হয় AAGUID সংশ্লিষ্ট পাসকির সাথে যুক্ত। AAGUID একটি পাসকি এর প্রমাণীকরণকারী ডেটার অংশ হিসাবে পাওয়া যেতে পারে।

উদাহরণস্বরূপ, যদি একজন ব্যবহারকারী Google পাসওয়ার্ড ম্যানেজার ব্যবহার করে একটি Android-চালিত ডিভাইসে একটি পাসকি তৈরি করে, তাহলে RP একটি AAGUID পায় যা দেখতে এইরকম কিছু: "ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4"। Google পাসওয়ার্ড ম্যানেজার ব্যবহার করে তৈরি করা হয়েছে তা নির্দেশ করার জন্য নির্ভরকারী পক্ষ পাসকি তালিকায় পাসকিটিকে টীকা দিতে পারে।

একটি পাসকি প্রদানকারীর কাছে একটি AAGUID ম্যাপ করতে, RPs AAGUID-এর একটি কমিউনিটি সোর্সড রিপোজিটরি ব্যবহার করতে পারে। পাসকি প্রদানকারীর নাম এবং আইকন খুঁজে পেতে তালিকায় AAGUID দেখুন।

AAGUID ইন্টিগ্রেশন সম্পর্কে আরও পড়ুন।

সাধারণ ত্রুটির সমস্যা সমাধান করুন

নিম্নলিখিত টেবিলটি বেশ কয়েকটি সাধারণ ত্রুটি কোড এবং বিবরণ দেখায় এবং তাদের কারণ সম্পর্কে কিছু তথ্য প্রদান করে:

ত্রুটি কোড এবং বিবরণ কারণ
শুরুতে সাইন ইন ব্যর্থতা: 16: অনেকগুলি ব�������� ��া��ন-ইন প্রম্পটের কারণে কলারকে সাময়িকভাবে অবরুদ্ধ করা হয়েছে৷

আপনি যদি বিকাশের সময় এই 24-ঘন্টা কুলডাউন সময়ের সম্মুখীন হন, আপনি Google Play পরিষেবার অ্যাপ স্টোরেজ সাফ করে এটি পুনরায় সেট করতে পারেন।

বিকল্পভাবে, একটি পরীক্ষা ডিভাইস বা এমুলেটরে এই কুলডাউনটি টগল করতে, ডায়লার অ্যাপে যান এবং নিম্নলিখিত কোডটি ইনপুট করুন: *#*#66382723#*#* । ডায়ালার অ্যাপটি সমস্ত ইনপুট সাফ করে এবং বন্ধ হতে পারে, কিন্তু একটি নিশ্চিতকরণ বার্তা নেই।

শুরুতে সাইন ইন ব্যর্থতা: 8: অজানা অভ্যন্তরীণ ত্রুটি৷
  1. ডিভাইসটি Google অ্যাকাউন্টের সাথে সঠিকভাবে সেট আপ করা হয়নি৷
  2. পাসকি JSON ভুলভাবে তৈরি করা হচ্ছে।
CreatePublicKeyCredentialDomException: আগত অনুরোধ যাচাই করা যাবে না অ্যাপটির প্যাকেজ আইডি আপনার সার্ভারে নিবন্ধিত নয়। আপনার সার্ভার-সাইড ইন্টিগ্রেশনে এটি যাচাই করুন।
CreateCredentialUnknownException: পাসওয়ার্ড সেভ করার সময়, একটি ট্যাপ থেকে পাসওয়ার্ড ব্যর্থতার প্রতিক্রিয়া পাওয়া গেছে 16: পাসওয়ার্ড সেভ করা এড়িয়ে যাওয়া যেহেতু ব্যবহারকারীকে Android Autofill-এর সাথে অনুরোধ করা হয়েছে এই ত্রুটিটি শুধুমাত্র Android 13 এবং তার নিচের সংস্করণে ঘটে এবং শুধুমাত্র Google অটোফিল প্রদানকারী হলে। এই ক্ষেত্রে, ব্যবহারকারীরা অটোফিল থেকে একটি সংরক্ষণ প্রম্পট দেখতে পান এবং পাসওয়ার্ডটি Google পাসওয়ার্ড ম্যানেজারে সংরক্ষিত হয়। মনে রাখবেন যে Google-এর সাথে অটোফিল ব্যবহার করে সংরক্ষিত শংসাপত্রগুলি ক্রেডেনশিয়াল ম্যানেজার এপিআই-এর সাথে দ্বিমুখীভাবে ভাগ করা হয়৷ ফলস্বরূপ, এই ত্রুটিটি নিরাপদে উপেক্ষা করা যেতে পারে।

অতিরিক্ত সম্পদ

ক্রেডেনশিয়াল ম্যানেজার API এবং পাসকি সম্পর্কে আরও জানতে, নিম্নলিখিত সংস্থানগুলি দেখুন: