সংশোধন ২০২৫ চতুর্থ ত্রৈমাসিকে: আপনার অ্যান্ড্রয়েড অ্যাপে ক্রেডেনশিয়াল ম্যানেজার API ব্যবহার করে প্রমাণীকরণ যাত্রা সহজ করার পদ্ধতি শিখুন

১. শুরু করার আগে

প্রচলিত প্রমাণীকরণ সমাধানগুলো বেশ কিছু নিরাপত্তা ও ব্যবহারযোগ্যতার চ্যালেঞ্জ তৈরি করে।

পাসওয়ার্ড বহুল ব্যবহৃত হয় কিন্তু...

  • সহজে ভুলে যাওয়া
  • শক্তিশালী পাসওয়ার্ড তৈরি করতে ব্যবহারকারীদের জ্ঞানের প্রয়োজন।
  • আক্রমণকারীদের জন্য ফিশিং করা, তথ্য সংগ্রহ করা এবং পুনরায় ব্যবহার করা সহজ।

অ্যান্ড্রয়েড সাইন-ইন অভিজ্ঞতা সহজ করতে এবং নিরাপত্তা ঝুঁকি মোকাবেলার জন্য ক্রেডেনশিয়াল ম্যানেজার এপিআই (Credential Manager API) তৈরিতে কাজ করেছে, যা পাসওয়ার্ডবিহীন প্রমাণীকরণের জন্য পরবর্তী প্রজন্মের শিল্পমান ‘পাসকি’ (passkey ) সমর্থন করে।

ক্রেডেনশিয়াল ম্যানেজার পাসকি-এর সুবিধাকে পাসওয়ার্ড, গুগল দিয়ে সাইন ইন ইত্যাদির মতো প্রচলিত প্রমাণীকরণ পদ্ধতির সাথে একত্রিত করে।

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

এই কোডল্যাবে, আপনি শিখবেন কিভাবে ক্রেডেনশিয়াল ম্যানেজার এপিআই (Credential Manager API) ব্যবহার করে পাসকি (passkey) এবং পাসওয়ার্ড (password) দিয়ে সাইন আপ করতে হয় এবং ভবিষ্যতের প্রমাণীকরণের (authentication) উদ্দেশ্যে সেগুলো ব্যবহার করতে হয়। এখানে ২টি ফ্লো (flow) রয়েছে, যার মধ্যে অন্তর্ভুক্ত:

  • নিবন্ধন করুন: পাসকি এবং পাসওয়ার্ড ব্যবহার করে।
  • সাইন ইন করুন : পাসকি ও সংরক্ষিত পাসওয়ার্ড ব্যবহার করে।

পূর্বশর্ত

  • অ্যান্ড্রয়েড স্টুডিওতে কীভাবে অ্যাপ চালাতে হয় সে সম্পর্কে প্রাথমিক ধারণা।
  • অ্যান্ড্রয়েড অ্যাপে অথেনটিকেশন ফ্লো সম্পর্কে প্রাথমিক ধারণা।
  • পাসকি সম্পর্কে প্রাথমিক ধারণা।

আপনি যা শিখবেন

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

আপনার যা যা লাগবে

নিম্নলিখিত ডিভাইস সংমিশ্রণগুলির মধ্যে একটি:

  • একটি অ্যান্ড্রয়েড ডিভাইস যা অ্যান্ড্রয়েড ৯ বা তার উচ্চতর সংস্করণে (পাসকির জন্য) এবং অ্যান্ড্রয়েড ৪.৪ বা তার উচ্চতর সংস্করণে (ক্রেডেনশিয়াল ম্যানেজার এপিআই-এর মাধ্যমে পাসওয়ার্ড প্রমাণীকরণের জন্য) চলে।
  • ডিভাইসটিতে বায়োমেট্রিক সেন্সর থাকা বাঞ্ছনীয়।
  • একটি স্ক্রিন লক (বায়োমেট্রিক বা অন্য কোনো উপায়ে) রেজিস্টার করতে ভুলবেন না।
  • কোটলিন প্লাগইন সংস্করণ : 1.8.10

২. প্রস্তুত হন

এই স্যাম্পল অ্যাপটির জন্য ক্রেডেনশিয়াল ম্যানেজারকে লিঙ্কিংটি ভ্যালিডেট করে সামনে এগোনোর জন্য একটি ওয়েবসাইটের সাথে ডিজিটাল অ্যাসেট লিঙ্ক করা প্রয়োজন, তাই মক রেসপন্সগুলোতে ব্যবহৃত rp id-টি একটি মকড 3P সার্ভার থেকে নেওয়া হয়েছে। আপনি যদি নিজের মক রেসপন্স তৈরি করতে চান, তাহলে আপনার অ্যাপ ডোমেইনটি যোগ করুন এবং এখানে উল্লিখিত নির্দেশনা অনুযায়ী ডিজিটাল অ্যাসেট লিঙ্কিং সম্পন্ন করতে ভুলবেন না।

আপনার মক সার্ভারে প্যাকেজ নেম এবং sha-এর ডিজিটাল অ্যাসেট লিঙ্কিং যাচাই করার জন্য, প্রজেক্টে উল্লিখিত একই debug.keystore ব্যবহার করে ডিবাগ এবং রিলিজ ভ্যারিয়েন্ট তৈরি করুন। (স্যাম্পল অ্যাপের জন্য এই কাজটি 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

৩. পাসকি ব্যবহার করে সাইন আপ করার সুবিধা যোগ করুন।

ক্রেডেনশিয়াল ম্যানেজার এপিআই (Credential Manager API) ব্যবহারকারী কোনো অ্যান্ড্রয়েড অ্যাপে নতুন অ্যাকাউন্ট খোলার সময়, ব্যবহারকারীরা তাদের অ্যাকাউন্টের জন্য একটি পাসকি (passkey) তৈরি করতে পারেন। এই পাসকিটি ব্যবহারকারীর নির্বাচিত ক্রেডেনশিয়াল প্রোভাইডারে নিরাপদে সংরক্ষিত থাকবে এবং ভবিষ্যতে সাইন-ইন করার জন্য ব্যবহৃত হবে, যার ফলে ব্যবহারকারীকে প্রতিবার পাসওয়ার্ড দিতে হবে না।

এখন, আপনি বায়োমেট্রিক্স/স্ক্রিন লক ব্যবহার করে একটি পাসকি তৈরি করবেন এবং ব্যবহারকারীর পরিচয়পত্র নিবন্ধন করবেন।

পাসকি দিয়ে সাইন আপ করুন

CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignUpScreen.kt ফাইলের ভেতরের কোডে 'username' নামে একটি টেক্সট ফিল্ড এবং একটি পাসকি দিয়ে সাইন আপ করার জন্য একটি বাটন নির্ধারণ করা হয়েছে।

1f4c50daa2551f1.jpeg

ভিউ মডেলে ব্যবহারের জন্য createCredential() ল্যাম্বডা সংজ্ঞায়িত করুন।

ক্রেডেনশিয়াল ম্যানেজার অবজেক্টের জন্য একটি 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 নামে একটি নমুনা প্রতিক্রিয়া (mock response) রয়েছে, যা এই কোডল্যাবের প্রয়োজনীয় প্যারামিটারগুলো ফেরত দেয়।

  • আপনার অ্যাপে, SignUpViewModel.kt ফাইলে যান এবং signUpWithPasskeys মেথডটি খুঁজুন, যেখানে আপনি একটি পাসকি তৈরি করার এবং ব্যবহারকারীকে প্রবেশ করানোর লজিক লিখবেন। আপনি মেথডটি একই ক্লাসের মধ্যে খুঁজে পাবেন।
  • create a CreatePublicKeyCredentialRequest() জন্য TODO কমেন্ট ব্লকটি খুঁজুন এবং নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

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() মেথডটি assets থেকে একটি অনুকৃত সার্ভারের PublicKeyCredentialCreationOptions JSON রেসপন্স পড়ে এবং পাসকি তৈরি করার সময় পাস করার জন্য রেজিস্ট্রেশন JSON রিটার্ন করে। আমরা কিছু প্লেসহোল্ডার ভ্যালুকে আমাদের অ্যাপ থেকে নেওয়া ইউজার এন্ট্রি এবং কিছু মকড ফিল্ড দিয়ে প্রতিস্থাপন করি:

  • এই JSON-টি অসম্পূর্ণ এবং এর ৪টি ফিল্ড প্রতিস্থাপন করা প্রয়োজন।
  • ইউজারআইডি অনন্য হওয়া প্রয়োজন, যাতে একজন ব্যবহারকারী (প্রয়োজনে) একাধিক পাসকি তৈরি করতে পারেন। <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

সার্ভার দ্বারা তৈরি একটি র‍্যান্ডম স্ট্রিং, যাতে এত বেশি এনট্রপি থাকে যে এটিকে অনুমান করা অসম্ভব। এর দৈর্ঘ্য কমপক্ষে ১৬ বাইট হতে হবে। এটি আবশ্যক, কিন্তু অ্যাটেস্টেশন করা ছাড়া রেজিস্ট্রেশনের সময় এটি ব্যবহৃত হয় না।

user.id

ব্যবহারকারীর অনন্য আইডি। এই মানে ব্যক্তিগত শনাক্তকারী তথ্য, যেমন ই-মেইল ঠিকানা বা ইউজারনেম অন্তর্ভুক্ত করা যাবে না। প্রতিটি অ্যাকাউন্টের জন্য তৈরি একটি র‍্যান্ডম, ১৬-বাইটের মান এক্ষেত্রে ভালোভাবে কাজ করবে।

user.name

এই ফিল্ডে অ্যাকাউন্টের জন্য একটি অনন্য শনাক্তকারী থাকা উচিত যা ব্যবহারকারী চিনতে পারবেন, যেমন তার ইমেল ঠিকানা বা ইউজারনেম। এটি অ্যাকাউন্ট সিলেক্টরে প্রদর্শিত হবে। (ইউজারনেম ব্যবহার করলে, পাসওয়ার্ড অথেনটিকেশনের জন্য ব্যবহৃত মানটিই ব্যবহার করুন।)

user.displayName

এই ফিল্ডটি অ্যাকাউন্টের জন্য একটি ঐচ্ছিক ও অধিক ব্যবহার-বান্ধব নাম।

rp.id

নির্ভরকারী পক্ষ সত্তাটি আপনার আবেদনের বিবরণের সাথে সঙ্গতিপূর্ণ। এর নিম্নলিখিত বৈশিষ্ট্যগুলো রয়েছে:

  • name (আবশ্যক): আপনার আবেদনের নাম
  • ID (ঐচ্ছিক): ডোমেইন বা সাবডোমেইনকে নির্দেশ করে। এটি অনুপস্থিত থাকলে, বর্তমান ডোমেইনটি ব্যবহৃত হয়।
  • icon (ঐচ্ছিক)।

pubKeyCredParams

অনুমোদিত অ্যালগরিদম এবং কী-টাইপের তালিকা। এই তালিকায় অবশ্যই অন্তত একটি উপাদান থাকতে হবে।

excludeCredentials

যে ব্যবহারকারী একটি ডিভাইস নিবন্ধন করার চেষ্টা করছেন, তিনি হয়তো ইতিমধ্যেই অন্যান্য ডিভাইস নিবন্ধন করে রেখেছেন। একটিমাত্র অথেন্টিকেটরে একই অ্যাকাউন্টের জন্য একাধিক ক্রেডেনশিয়াল তৈরি হওয়া সীমিত করতে, আপনি তখন এই ডিভাইসগুলোকে উপেক্ষা করতে পারেন। ` 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)
}

  • আপনি রেন্ডার করা ভিউগুলোর দৃশ্যমানতা নিয়ন্ত্রণ করেন এবং কোনো কারণে অনুরোধ ব্যর্থ বা অসফল হলে এক্সেপশনগুলো পরিচালনা করেন। এখানে ত্রুটির বার্তাগুলো লগ করা হয় এবং অ্যাপের একটি এরর ডায়ালগে দেখানো হয়। আপনি অ্যান্ড্রয়েড স্টুডিও অথবা adb debug কমান্ডের মাধ্যমে সম্পূর্ণ এরর লগগুলো দেখতে পারেন।

1ea8ace66135de1e.png

  1. অবশেষে, আপনাকে নিবন্ধন প্রক্রিয়াটি সম্পন্ন করতে হবে। অ্যাপটি সার্ভারে একটি পাবলিক কী ক্রেডেনশিয়াল পাঠায়, যা বর্তমান ব্যবহারকারীর নামে সেটিকে নিবন্ধন করে দেয়।

এখানে, আমরা একটি মক সার্ভার ব্যবহার করেছি, তাই আমরা শুধু 'true' রিটার্ন করছি, যা নির্দেশ করে যে সার্ভারটি ভবিষ্যতের প্রমাণীকরণ এবং যাচাইকরণের উদ্দেশ্যে নিবন্ধিত পাবলিক কী সংরক্ষণ করেছে। আপনার নিজস্ব বাস্তবায়নের জন্য আপনি সার্ভার-সাইড পাসকী নিবন্ধন সম্পর্কে আরও পড়তে পারেন।

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 এনকোডেড অ্যাটেস্টেশন অবজেক্ট। এতে RP ID, ফ্ল্যাগ এবং পাবলিক কী-এর মতো গুরুত্বপূর্ণ তথ্য থাকে।

অ্যাপটি চালান, এবং আপনি 'Sign up with passkeys' বোতামে ক্লিক করে একটি পাসকি তৈরি করতে পারবেন।

৪. ক্রেডেনশিয়াল প্রোভাইডারে একটি পাসওয়ার্ড সংরক্ষণ করুন।

এই অ্যাপটির সাইন-আপ স্ক্রিনে, প্রদর্শনের উদ্দেশ্যে ইউজারনেম এবং পাসওয়ার্ড দিয়ে সাইন-আপ করার একটি ব্যবস্থা আগে থেকেই যুক্ত করা আছে।

ব্যবহারকারীর পাসওয়ার্ড প্রোভাইডারের কাছে তার পাসওয়ার্ড ক্রেডেনশিয়াল সংরক্ষণ করতে, আপনাকে একটি 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
    }

এখন আপনি ব্যবহারকারীর পাসওয়ার্ড প্রদানকারীর কাছে পাসওয়ার্ডের তথ্য সফলভাবে সংরক্ষণ করেছেন, যাতে মাত্র এক ট্যাপেই পাসওয়ার্ড দিয়ে প্রমাণীকরণ করা যায়।

৫. পাসকি বা পাসওয়ার্ড দিয়ে প্রমাণীকরণের সুবিধা যোগ করুন।

এখন আপনি আপনার অ্যাপে নিরাপদে প্রমাণীকরণের উপায় হিসেবে এটি ব্যবহার করতে প্রস্তুত।

76e81460b26f9798.png

ভিউ মডেলে ব্যবহারের জন্য getCredential() ল্যাম্বডা সংজ্ঞায়িত করুন।

আগের মতোই, আমরা ক্রেডেনশিয়াল ম্যানেজারের getCredential() CredentialManagerUtil.kt নামক একটি পৃথক ফাইলে কল করব, যাতে উপযুক্ত স্ক্রিনগুলিতে এটিকে রেফারেন্স হিসেবে ব্যবহার করা যায় এবং ল্যাম্বডা ফাংশনের মাধ্যমে কলব্যাক হিসেবে তাদের ভিউ মডেলগুলিতে পাঠানো যায়।

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() ` মেথডটি `assets` থেকে অথেনটিকেশন JSON রেসপন্স পড়ে এবং এই ইউজার অ্যাকাউন্টের সাথে যুক্ত সমস্ত পাসকি পুনরুদ্ধার করার জন্য অথেনটিকেশন JSON রিটার্ন করে।

GetPublicKeyCredentialOption() এর ২য় প্যারামিটারটি হলো clientDataHash – এটি এমন একটি হ্যাশ যা রিলায়িং পার্টির পরিচয় যাচাই করতে ব্যবহৃত হয়। এটি কেবল তখনই সেট করুন যখন আপনি GetCredentialRequest.origin সেট করেছেন। স্যাম্পল অ্যাপটির জন্য, এটি null সেট করা আছে।

দ্রষ্টব্য: এই কোডল্যাবের সার্ভারটি এমনভাবে ডিজাইন করা হয়েছে যাতে এটি API-এর getCredential() কলে পাঠানো PublicKeyCredentialRequestOptions ডিকশনারির সাথে যথাসম্ভব সাদৃশ্যপূর্ণ একটি JSON রিটার্ন করে। নিম্নলিখিত কোড স্নিপেটটিতে কয়েকটি উদাহরণ অপশন অন্তর্ভুক্ত রয়েছে যা আপনি একটি বাস্তব রেসপন্সে পেতে পারেন:

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

নিম্নলিখিত সারণিতে একটি PublicKeyCredentialRequestOptions অবজেক্টের কিছু গুরুত্বপূর্ণ প্যারামিটার ব্যাখ্যা করা হয়েছে:

প্যারামিটার

বর্ণনা

challenge

একটি ArrayBuffer অবজেক্টে সার্ভার-উৎপাদিত একটি চ্যালেঞ্জ। রিপ্লে অ্যাটাক প্রতিরোধ করার জন্য এটি প্রয়োজন। একটি রেসপন্সে কখনোই একই চ্যালেঞ্জ দুইবার গ্রহণ করবেন না। এটিকে একটি CSRF টোকেন হিসেবে বিবেচনা করুন।

rpId

আরপি আইডি হলো একটি ডোমেইন। একটি ওয়েবসাইট তার নিজস্ব ডোমেইন অথবা একটি নিবন্ধনযোগ্য সাফিক্স উল্লেখ করতে পারে। এই মানটি অবশ্যই পাসকি তৈরির সময় ব্যবহৃত rp.id প্যারামিটারের সাথে মিলতে হবে।

  • এরপরে, এই ইউজার অ্যাকাউন্টের জন্য ক্রেডেনশিয়াল ম্যানেজার এপিআই (Credential Manager API)-এর মাধ্যমে আপনার পাসওয়ার্ড প্রোভাইডারে সংরক্ষিত সমস্ত পাসওয়ার্ড পুনরুদ্ধার করতে আপনাকে একটি PasswordOption() অবজেক্ট তৈরি করতে হবে। getSavedCredentials() মেথডের ভিতরে, TODO অংশটি খুঁজুন এবং নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

সাইনইনভিউমডেল.কেটি

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

val getPasswordOption = GetPasswordOption()

এগুলোকে একটি GetCredentialRequest এ একত্রিত করুন।

সাইনইনভিউমডেল.কেটি

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 অবজেক্ট। এই ফিল্ডটিতে চ্যালেঞ্জ এবং অরিজিনের মতো তথ্য থাকে, যা RP সার্ভারকে যাচাই করতে হয়।

response.authenticatorData

অথেন্টিকেটর ডেটার একটি ArrayBuffer অবজেক্ট। এই ফিল্ডটিতে RP ID-এর মতো তথ্য থাকে।

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() ফাংশনটি 'true' রিটার্ন করে, যা নির্দেশ করে যে (মক) সার্ভার ভবিষ্যতের ব্যবহারের জন্য পাবলিক কী-টি যাচাই করেছে।
  • একবার লগ ইন করলে, আপনি আপনার ব্যবহারকারীকে হোম স্ক্রিনে পাঠিয়ে দেবেন।

অ্যাপটি চালু করুন এবং সাইন ইন > পাসকি/সংরক্ষিত পাসওয়ার্ড দিয়ে সাইন ইন-এ যান, এবং সংরক্ষিত ক্রেডেনশিয়াল ব্যবহার করে সাইন ইন করার চেষ্টা করুন।

চেষ্টা করে দেখুন

আপনি আপনার অ্যান্ড্রয়েড অ্যাপে পাসকি তৈরি করা, ক্রেডেনশিয়াল ম্যানেজারে পাসওয়ার্ড সংরক্ষণ করা এবং ক্রেডেনশিয়াল ম্যানেজার এপিআই ব্যবহার করে পাসকি বা সংরক্ষিত পাসওয়ার্ডের মাধ্যমে প্রমাণীকরণের ব্যবস্থা বাস্তবায়ন করেছেন।

৬. অভিনন্দন!

আপনি এই কোডল্যাবটি শেষ করেছেন! আপনি যদি চূড়ান্ত সমাধানটি দেখতে চান, তবে সেটি https://github.com/android/identity-samples/tree/main/CredentialManager -এ উপলব্ধ আছে।

আপনার কোনো প্রশ্ন থাকলে, passkey ট্যাগ ব্যবহার করে স্ট্যাকওভারফ্লোতে জিজ্ঞাসা করুন।

আরও জানুন