একটি ওয়েব অ্যাপে ফর্ম অটোফিল সহ পাসকিগুলি প্রয়োগ করুন৷

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

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

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

  • এমন একটি বাটন যা ব্যবহারকারী সাইন ইন করার পর একটি পাসকি তৈরি করে।
  • একটি ইউজার ইন্টারফেস যা নিবন্ধিত পাসকিগুলোর তালিকা প্রদর্শন করে।
  • বিদ্যমান সাইন-ইন ফর্মটি ব্যবহারকারীদের একটি নিবন্ধিত পাসকি দিয়ে ফর্ম অটোফিলের মাধ্যমে সাইন ইন করতে দেয়।

পূর্বশর্ত

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

  • কীভাবে একটি পাসকি তৈরি করবেন।
  • পাসকি ব্যবহার করে ব্যবহারকারীদের প্রমাণীকরণ কীভাবে করবেন।
  • কীভাবে একটি ফর্মকে সাইন-ইন বিকল্প হিসাবে পাসকি প্রস্তাব করতে দেওয়া যায়

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

এই কোডল্যাবে, আপনি গিটহাব থেকে একটি অসম্পূর্ণ ডেমো অ্যাপ ক্লোন করবেন এবং তারপর পাসকি সাপোর্টের বাস্তবায়ন সম্পন্ন করবেন।

প্রকল্পটি ক্লোন করুন

  1. গিটহাবে প্রজেক্টটি খুলুন।
  2. প্রজেক্টটি ক্লোন বা ডাউনলোড করুন।

ac587c53b746785a.png

প্রকল্পটি চালান

  1. টার্মিনাল খুলে ডিরেক্টরি পরিবর্তন করতে cd start
  2. প্রজেক্টের নির্ভরতাগুলো ইনস্টল করতে npm install চালান।
  3. npm run build && IS_LOCAL=1 npm run start . কমান্ড দিয়ে প্রজেক্টটি বিল্ড ও রান করুন।
  4. আপনার ব্রাউজারে http://localhost:8080/ খুলুন।

ওয়েবসাইটটির প্রাথমিক অবস্থা পরীক্ষা করুন

  1. সাইটে একটি এলোমেলো ইউজারনেম লিখুন এবং তারপর 'Next'-এ ক্লিক করুন।
  2. একটি এলোমেলো পাসওয়ার্ড দিন এবং তারপর সাইন-ইন-এ ক্লিক করুন। পাসওয়ার্ডটি উপেক্ষা করা হবে, কিন্তু আপনার পরিচয় যাচাই হয়ে যাবে এবং আপনি হোম পেজে চলে আসবেন।
  3. আপনি যদি আপনার প্রদর্শিত নাম পরিবর্তন করতে চান, তবে তা করতে পারেন। প্রাথমিক অবস্থায় এর বেশি কিছু করার নেই।
  4. সাইন আউট-এ ক্লিক করুন।

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

পাসকি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য, “পাসকি কীভাবে কাজ করে?” দেখুন।

৩. পাসকি তৈরি করার সুবিধা যোগ করুন

ব্যবহারকারীদের পাসকি দিয়ে প্রমাণীকরণের সুযোগ দিতে হলে, তাদেরকে একটি পাসকি তৈরি ও নিবন্ধন করার সুবিধা দিতে হবে এবং এর পাবলিক কী সার্ভারে সংরক্ষণ করতে হবে।

9b84dbaec66afe9c.png

আপনি চান যে ব্যবহারকারী পাসওয়ার্ড দিয়ে লগ ইন করার পর একটি পাসকি তৈরি করতে পারবে এবং এমন একটি ইউজার ইন্টারফেস (UI) যোগ করতে চান যা ব্যবহারকারীদের /home পেজে একটি পাসকি তৈরি করতে ও সমস্ত নিবন্ধিত পাসকি-র তালিকা দেখতে দেবে। পরবর্তী অংশে, আপনি একটি ফাংশন তৈরি করবেন যা একটি পাসকি তৈরি ও নিবন্ধন করবে।

registerCredential() ফাংশনটি তৈরি করুন

  1. আপনার পছন্দের কোড এডিটরে start ডিরেক্টরিটি খুলুন।
  2. public/client.js ফাইলটিতে যান এবং তারপর একদম শেষে স্ক্রল করুন।
  3. প্রাসঙ্গিক মন্তব্যের পরে, নিম্নলিখিত registerCredential() ফাংশনটি যোগ করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to create a passkey: Create the registerCredential() function.
export async function registerCredential() {

  // TODO: Add an ability to create a passkey: Obtain the challenge and other options from the server endpoint.

  // TODO: Add an ability to create a passkey: Create a credential.

  // TODO: Add an ability to create a passkey: Register the credential to the server endpoint.

};

এই ফাংশনটি সার্ভারে একটি পাসকি তৈরি ও নিবন্ধন করে।

সার্ভার এন্ডপয়েন্ট থেকে চ্যালেঞ্জ এবং অন্যান্য বিকল্পগুলো সংগ্রহ করুন।

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

  • সার্ভার এন্ডপয়েন্ট থেকে চ্যালেঞ্জ এবং অন্যান্য অপশনগুলো পেতে, registerCredential() ফাংশনের বডিতে প্রাসঙ্গিক কমেন্টের পরে নিম্নলিখিত কোডটি যোগ করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to create a passkey: Obtain the challenge and other options from the server endpoint.
const _options = await _fetch('/auth/registerRequest');

নিম্নলিখিত কোড স্নিপেটটিতে সার্ভার থেকে প্রাপ্ত নমুনা অপশনগুলো অন্তর্ভুক্ত রয়েছে:

{
  challenge: *****,
  rp: {
    id: "example.com",
  },
  user: {
    id: *****,
    name: "john78",
    displayName: "John",
  },  
  pubKeyCredParams: [{
    alg: -7, type: "public-key"
  },{
    alg: -257, type: "public-key"
  }],
  excludeCredentials: [{
    id: *****,
    type: 'public-key',
    transports: ['internal', 'hybrid'],
  }],
  authenticatorSelection: {
    authenticatorAttachment: "platform",
    requireResidentKey: true,
  }
}

সার্ভার এবং ক্লায়েন্টের মধ্যকার প্রোটোকলটি WebAuthn স্পেসিফিকেশনের অংশ নয়। তবে, এই কোডল্যাবের সার্ভারটিকে এমনভাবে ডিজাইন করা হয়েছে যাতে এটি এমন একটি JSON রিটার্ন করে যা WebAuthn-এর navigator.credentials.create() API-তে পাস করা PublicKeyCredentialCreationOptions ডিকশনারিটির সাথে যথাসম্ভব সাদৃশ্যপূর্ণ।

নিম্নলিখিত সারণীটি সম্পূর্ণ নয়, তবে এতে PublicKeyCredentialCreationOptions ডিকশনারির গুরুত্বপূর্ণ প্যারামিটারগুলো রয়েছে:

প্যারামিটার

বর্ণনা

challenge

এই রেজিস্ট্রেশনের জন্য একটি ArrayBuffer অবজেক্টে সার্ভার-জেনারেটেড একটি চ্যালেঞ্জ। এটি প্রয়োজনীয় হলেও রেজিস্ট্রেশনের সময় ব্যবহৃত হয় না, যদি না অ্যাটেস্টেশন করা হয় — যা একটি উন্নত বিষয় এবং এই কোডল্যাবে আলোচনা করা হয়নি।

user.id

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

user.name

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

user.displayName

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

rp.id

একটি রিলায়িং পার্টি (RP) আইডি হলো একটি ডোমেইন। একটি ওয়েবসাইট তার নিজস্ব ডোমেইন অথবা একটি নিবন্ধনযোগ্য সাফিক্স উল্লেখ করতে পারে। উদাহরণস্বরূপ, যদি একটি RP-এর অরিজিন https://login.example.com:1337 হয়, তাহলে RP আইডিটি login.example.com অথবা example.com হতে পারে। যদি RP আইডিটি example.com হিসেবে উল্লেখ করা হয়, তাহলে ব্যবহারকারী login.example.com-এ অথবা example.com-এর অন্য যেকোনো সাবডোমেইনে প্রমাণীকরণ করতে পারবেন।

pubKeyCredParams

এই ফিল্ডটি RP-এর সমর্থিত পাবলিক-কী অ্যালগরিদমগুলো নির্দিষ্ট করে। আমরা এটিকে [{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}] -এ সেট করার পরামর্শ দিই। এটি P-256 সহ ECDSA এবং RSA PKCS#1 -এর জন্য সমর্থন নির্দিষ্ট করে, এবং এগুলোকে সমর্থন করলে সম্পূর্ণ কভারেজ পাওয়া যায়।

excludeCredentials

একই ডিভাইসের নিবন্ধন দুবার হওয়া রোধ করতে ইতিমধ্যে নিবন্ধিত ক্রেডেনশিয়াল আইডিগুলির একটি তালিকা প্রদান করে। যদি এটি প্রদান করা হয়, তবে প্রতিটি ক্রেডেনশিয়ালের নিবন্ধনের সময় getTransports() ফাংশনটি কল করার ফলাফল transports মেম্বারটিতে থাকা উচিত। একটি পাসকি বিদ্যমান থাকলে কীভাবে নতুন পাসকি তৈরি হওয়া রোধ করা যায় , সে সম্পর্কে আরও জানতে আমাদের ডকুমেন্টেশন দেখুন।

authenticatorSelection.authenticatorAttachment

"platform" ভ্যালুতে সেট করুন। এর মানে হলো, আপনি এমন একটি অথেন্টিকেটর চান যা প্ল্যাটফর্ম ডিভাইসের মধ্যেই এমবেড করা থাকবে, ফলে ব্যবহারকারীকে ইউএসবি সিকিউরিটি কী-এর মতো কোনো কিছু ঢোকাতে বলা হবে না।

authenticatorSelection.requireResidentKey

একটি বুলিয়ান ' true মানে সেট করা। একটি ডিসকভারেবল ক্রেডেনশিয়াল (রেসিডেন্ট কী) ব্যবহার করার জন্য সার্ভারকে ক্রেডেনশিয়ালটির আইডি প্রদান করতে হয় না এবং তাই এটি অটোফিলের সাথে সামঞ্জস্যপূর্ণ। আমাদের ডিসকভারেবল ক্রেডেনশিয়ালস বিষয়ক বিস্তারিত আলোচনায় এ সম্পর্কে আরও জানুন।

authenticatorSelection.userVerification

একটি "preferred" মান সেট করুন অথবা এটি ডিফল্ট মান হওয়ায় বাদ দিন। এটি নির্দেশ করে যে ডিভাইসের স্ক্রিন লক ব্যবহার করে ব্যবহারকারী যাচাইকরণ "required" , "preferred" , নাকি "discouraged""preferred" মান সেট করলে, ডিভাইসটি সক্ষম হলে ব্যবহারকারী যাচাইকরণের জন্য অনুরোধ করা হয়। আমাদের userVerification বিষয়ক বিস্তারিত আলোচনায় আরও জানুন।

একটি পরিচয়পত্র তৈরি করুন

  1. registerCredential() ফাংশনের বডিতে প্রাসঙ্গিক কমেন্টের পরে, Base64URL দিয়ে এনকোড করা কিছু প্যারামিটারকে আবার বাইনারিতে রূপান্তর করুন, বিশেষ করে user.id এবং challenge স্ট্রিং, এবং excludeCredentials অ্যারেতে অন্তর্ভুক্ত id স্ট্রিং-এর ইনস্ট্যান্সগুলোকে। এটি PublicKeyCredential.parseCreationOptionsFromJSON() ফাংশন দিয়ে করা যেতে পারে:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to create a passkey: Create a credential.

// Deserialize and decode the `PublicKeyCredential.parseCreationOptionsFromJSON()`.
const options = PublicKeyCredential.parseCreationOptionsFromJSON(_options);
  1. পরবর্তী লাইনে, authenticatorSelection.authenticatorAttachment কে "platform" এবং authenticatorSelection.requireResidentKey কে true সেট করুন। এর ফলে শুধুমাত্র একটি ডিসকভারেবল ক্রেডেনশিয়াল সক্ষমতাসহ প্ল্যাটফর্ম অথেন্টিকেটর (ডিভাইসটি নিজে) ব্যবহার করা যাবে।

পাবলিক/ক্লায়েন্ট.জেএস

// Use platform authenticator and discoverable credential.
options.authenticatorSelection = {
  authenticatorAttachment: 'platform',
  requireResidentKey: true
}
  1. পরবর্তী লাইনে, একটি ক্রেডেনশিয়াল তৈরি করতে navigator.credentials.create() মেথডটি কল করুন।

পাবলিক/ক্লায়েন্ট.জেএস

// Invoke the WebAuthn create() method.
const cred = await navigator.credentials.create({
  publicKey: options,
});

এই কলের মাধ্যমে ব্রাউজারটি ডিভাইসের স্ক্রিন লক ব্যবহার করে ব্যবহারকারীর পরিচয় যাচাই করার চেষ্টা করে।

সার্ভার এন্ডপয়েন্টে ক্রেডেনশিয়ালটি রেজিস্টার করুন।

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

নিম্নলিখিত কোড স্নিপেটটিতে একটি উদাহরণ ক্রেডেনশিয়াল অবজেক্ট রয়েছে:

{
  "id": *****,
  "rawId": *****,
  "type": "public-key",
  "response": {
    "clientDataJSON": *****,
    "attestationObject": *****,
    "transports": ["internal", "hybrid"]
  },
  "authenticatorAttachment": "platform"
}

নিচের সারণিটি সম্পূর্ণ নয়, তবে এতে PublicKeyCredential অবজেক্টের গুরুত্বপূর্ণ প্যারামিটারগুলো রয়েছে:

প্যারামিটার

বর্ণনা

id

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

rawId

ক্রেডেনশিয়াল আইডি-র একটি ArrayBuffer অবজেক্ট সংস্করণ।

response.clientDataJSON

একটি ArrayBuffer অবজেক্টে এনকোড করা ক্লায়েন্ট ডেটা।

response.attestationObject

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

response.transports

ডিভাইসটি যে সকল ট্রান্সপোর্ট সমর্থন করে তার একটি তালিকা: "internal" মানে ডিভাইসটি একটি পাসকি সমর্থন করে। "hybrid" মানে এটি অন্য কোনো ডিভাইসেও প্রমাণীকরণ সমর্থন করে।

authenticatorAttachment

যখন এই ক্রেডেনশিয়ালটি কোনো পাসকি-সক্ষম ডিভাইসে তৈরি করা হয়, তখন "platform" রিটার্ন করে।

সার্ভারে ক্রেডেনশিয়াল অবজেক্টটি পাঠাতে, এই ধাপগুলো অনুসরণ করুন:

  1. ক্রেডেনশিয়ালের বাইনারি প্যারামিটারগুলোকে Base64URL হিসেবে এনকোড করুন, যাতে এটি সার্ভারে একটি স্ট্রিং হিসেবে পাঠানো যায়। এই কাজটি করার জন্য আপনি .toJSON() ব্যবহার করতে পারেন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to create a passkey: Register the credential to the server endpoint.

// Encode and serialize the `PublicKeyCredential`.
const credential = JSON.stringify(cred);
  1. পরবর্তী লাইনে, অবজেক্টটি সার্ভারে পাঠান:

পাবলিক/ক্লায়েন্ট.জেএস

return await _fetch('/auth/registerResponse', credential);

যখন আপনি প্রোগ্রামটি চালান, তখন সার্ভার HTTP code 200 ফেরত দেয়, যা নির্দেশ করে যে ক্রেডেনশিয়ালটি নিবন্ধিত হয়েছে।

এখন আপনার কাছে সম্পূর্ণ registerCredential() ফাংশনটি রয়েছে!

এই অংশের সমাধান কোডটি পর্যালোচনা করুন।

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to create a passkey: Create the registerCredential() function.

export async function registerCredential() {

  // TODO: Add an ability to create a passkey: Obtain the challenge and other options from the server endpoint.

  const _options = await _fetch('/auth/registerRequest');

  // TODO: Add an ability to create a passkey: Create a credential.

  // Deserialize and decode the `PublicKeyCredential.parseCreationOptionsFromJSON()`.
  const options = PublicKeyCredential.parseCreationOptionsFromJSON(_options);

  // Use platform authenticator and discoverable credential.
  options.authenticatorSelection = {
    authenticatorAttachment: 'platform',
    requireResidentKey: true
  }

  // Invoke the WebAuthn create() method.
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // TODO: Add an ability to create a passkey: Register the credential to the server endpoint.

  // Encode and serialize the `PublicKeyCredential`.
  const credential = JSON.stringify(cred);

  return await _fetch('/auth/registerResponse', credential);
};

৪. পাসকি ক্রেডেনশিয়াল নিবন্ধন এবং পরিচালনা করার জন্য একটি UI তৈরি করুন।

এখন যেহেতু registerCredential() ফাংশনটি উপলব্ধ, এটিকে চালু করার জন্য আপনার একটি বাটন প্রয়োজন। এছাড়াও, আপনাকে নিবন্ধিত পাসকিগুলোর একটি তালিকা প্রদর্শন করতে হবে।

bfa4e7cdda47669e.png

প্লেসহোল্ডার HTML যোগ করুন

  1. আপনার এডিটরে views/home.html ফাইলটিতে যান।
  2. প্রাসঙ্গিক মন্তব্যের পরে, একটি UI প্লেসহোল্ডার যোগ করুন যা একটি পাসকি নিবন্ধন করার জন্য একটি বাটন এবং পাসকিগুলোর একটি তালিকা প্রদর্শন করবে:

ভিউ/হোম.এইচটিএমএল

​​<!-- TODO: Add an ability to create a passkey: Add placeholder HTML. -->
<section>
  <h3>Your registered passkeys:</h3>
  <div id="list"></div>
</section>
<p id="message" class="instructions"></p>
<mdui-button id="create-passkey" class="hidden" icon="fingerprint" type="button">Create a passkey</mdui-button>

div#list এলিমেন্টটি হলো তালিকার জন্য স্থানধারক।

পাসকি সমর্থনের জন্য পরীক্ষা করুন

শুধুমাত্র পাসকি সমর্থনকারী ডিভাইসের ব্যবহারকারীদের পাসকি তৈরির বিকল্পটি দেখানোর জন্য, আপনাকে প্রথমে যাচাই করতে হবে যে WebAuthn উপলব্ধ আছে কিনা। যদি থাকে, তাহলে 'Create a passkey' বাটনটি দেখানোর জন্য আপনাকে hidden ক্লাসটি সরিয়ে ফেলতে হবে।

কোনো পরিবেশে পাসকি সমর্থিত কিনা তা পরীক্ষা করতে, এই ধাপগুলো অনুসরণ করুন:

  1. views/home.html ফাইলের শেষে প্রাসঙ্গিক কমেন্টের পরে, এমন একটি কন্ডিশনাল লিখুন যা তখনই এক্সিকিউট হবে যখন window.PublicKeyCredential , PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable , এবং PublicKeyCredential.isConditionalMediationAvailable true হবে।

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Check for passkey support.
const createPasskey = $('#create-passkey');
// Feature detections
if (window.PublicKeyCredential &&
    PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable &&
    PublicKeyCredential.isConditionalMediationAvailable) {
  1. শর্তের মূল অংশে, ডিভাইসটি পাসকি তৈরি করতে পারে কিনা তা যাচাই করুন এবং তারপর ফর্ম অটোফিলে পাসকিটি প্রস্তাব করা যায় কিনা তা পরীক্ষা করুন।

ভিউ/হোম.এইচটিএমএল

try {
    const capabilities = await PublicKeyCredential.getClientCapabilities();
    // Is conditional UI available in this browser?
    if (capabilities.conditionalGet === true &&
        capabilities.passkeyPlatformAuthenticator === true) {
  1. সকল শর্ত পূরণ হলে, পাসকি তৈরি করার বাটনটি দেখান। অন্যথায়, একটি সতর্কীকরণ বার্তা দেখান।

ভিউ/হোম.এইচটিএমএল

      createPasskey.classList.remove('hidden');
    } else {

      // If conditional UI isn't available, show a message.
      $('#message').innerText = 'This device does not support passkeys.';
    }
  } catch (e) {
    console.error(e);
  }
} else {

  // If WebAuthn isn't available, show a message.
  $('#message').innerText = 'This device does not support passkeys.';
}

নিবন্ধিত পাসকিগুলো একটি তালিকায় প্রদর্শন করুন।

  1. একটি renderCredentials() ফাংশন সংজ্ঞায়িত করুন যা সার্ভার থেকে নিবন্ধিত পাসকিগুলো সংগ্রহ করে এবং সেগুলোকে একটি তালিকায় প্রদর্শন করে। সৌভাগ্যবশত, সাইন-ইন করা ব্যবহারকারীর নিবন্ধিত পাসকিগুলো সংগ্রহ করার জন্য আপনার কাছে ইতিমধ্যেই /auth/getKeys সার্ভার এন্ডপয়েন্টটি রয়েছে।

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Render registered passkeys in a list.
async function renderCredentials() {
  const res = await _fetch('/auth/getKeys');
  const list = $('#list');
  const creds = res.length > 0 ? html`
    <mdui-list>
      ${res.map(cred => html`
        <mdui-list-item>
          ${cred.name || 'Unnamed'}
          <mdui-button-icon data-cred-id="${cred.id}" data-name="${cred.name || 'Unnamed'}" @click="${rename}" icon="edit" slot="end-icon"></mdui-button-icon>
          <mdui-button-icon data-cred-id="${cred.id}" @click="${remove}" icon="delete" slot="end-icon"></mdui-button-icon>
        </mdui-list-item>`)}
    </mdui-list>` : html`
    <mdui-list>
      <mdui-list-item>No credentials found.</mdui-list-item>
    </mdui-list>`;
  render(creds, list);
};
  1. পরবর্তী লাইনে, ব্যবহারকারী /home পৃষ্ঠায় প্রবেশ করার সাথে সাথেই প্রারম্ভিক পর্যায় হিসেবে নিবন্ধিত পাসকিগুলো প্রদর্শন করার জন্য renderCredentials() ফাংশনটি কল করুন।

ভিউ/হোম.এইচটিএমএল

renderCredentials();

একটি পাসকি তৈরি ও নিবন্ধন করুন

একটি পাসকি তৈরি ও নিবন্ধন করতে, আপনাকে পূর্বে ইমপ্লিমেন্ট করা registerCredential() ফাংশনটি কল করতে হবে।

'Create a passkey' বোতামে ক্লিক করার পর registerCredential() ফাংশনটি চালু করতে, এই ধাপগুলো অনুসরণ করুন:

  1. ফাইলটিতে প্লেসহোল্ডার HTML-এর পরে, নিম্নলিখিত import স্টেটমেন্টটি খুঁজুন:

ভিউ/হোম.এইচটিএমএল

import { 
  $, 
  _fetch, 
  loading, 
  updateCredential, 
  unregisterCredential, 
} from '/client.js';
  1. import স্টেটমেন্টের বডির শেষে registerCredential() ফাংশনটি যোগ করুন।

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Create and register a passkey.
import {
  $,
  _fetch,
  loading,
  updateCredential,
  unregisterCredential,
  registerCredential
} from '/client.js';
  1. ফাইলের শেষে প্রাসঙ্গিক কমেন্টের পরে, একটি register() ফাংশন সংজ্ঞায়িত করুন যা registerCredential() ফাংশন ও একটি লোডিং UI চালু করে এবং রেজিস্ট্রেশনের পরে renderCredentials() ফাংশনকে কল করে। এর মাধ্যমে এটি স্পষ্ট হয় যে, কোনো সমস্যা হলে ব্রাউজার একটি পাসকি তৈরি করে এবং একটি এরর মেসেজ দেখায়।

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Create and register a passkey.
async function register() {
  try {

    // Start the loading UI.
    loading.start();

    // Start creating a passkey.
    await registerCredential();

    // Stop the loading UI.
    loading.stop();

    // Render the updated passkey list.
    renderCredentials();
  1. register() ফাংশনের বডিতে এক্সেপশন ক্যাচ করুন। ডিভাইসে পাসকি আগে থেকেই বিদ্যমান থাকলে navigator.credentials.create() মেথডটি একটি InvalidStateError এরর থ্রো করে। এটি excludeCredentials অ্যারের মাধ্যমে পরীক্ষা করা হয়। এক্ষেত্রে আপনি ব্যবহারকারীকে একটি প্রাসঙ্গিক বার্তা দেখান। ব্যবহারকারী অথেনটিকেশন ডায়ালগ বাতিল করলে এটি একটি NotAllowedError এররও থ্রো করে। এক্ষেত্রে আপনি এটিকে নীরবে উপেক্ষা করেন।

ভিউ/হোম.এইচটিএমএল

  } catch (e) {

    // Stop the loading UI.
    loading.stop();

    // An InvalidStateError indicates that a passkey already exists on the device.
    if (e.name === 'InvalidStateError') {
      alert('A passkey already exists for this device.');

    // A NotAllowedError indicates that the user canceled the operation.
    } else if (e.name === 'NotAllowedError') {
      Return;

    // Show other errors in an alert.
    } else {
      alert(e.message);
      console.error(e);
    }
  }
};
  1. register() ফাংশনের পরের লাইনে, 'Create a passkey ' বাটনের click ইভেন্টের সাথে register() ফাংশনটি সংযুক্ত করুন।

ভিউ/হোম.এইচটিএমএল

createPasskey.addEventListener('click', register);

এই অংশের সমাধান কোডটি পর্যালোচনা করুন।

ভিউ/হোম.এইচটিএমএল

<!-- TODO: Add an ability to create a passkey: Add placeholder HTML. -->
<section>
  <h3>Your registered passkeys:</h3>
  <div id="list"></div>
</section>
<p id="message" class="instructions"></p>
<mdui-button id="create-passkey" icon="fingerprint" type="button">Create a passkey</mdui-button>

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Create and register a passkey.
import { 
  $, 
  _fetch, 
  loading, 
  updateCredential, 
  unregisterCredential, 
  registerCredential 
} from '/client.js';

ভিউ/হোম.এইচটিএমএল

// TODO: Add an ability to create a passkey: Check for passkey support.
const createPasskey = $('#create-passkey');

// Is WebAuthn available in this browser?
if (window.PublicKeyCredential &&
  PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable &&
  PublicKeyCredential.isConditionalMediationAvailable) {
  try {
    const capabilities = await PublicKeyCredential.getClientCapabilities();
    // Is conditional UI available in this browser?
    if (capabilities.conditionalGet === true &&
      capabilities.passkeyPlatformAuthenticator === true) {
      // If conditional UI is available, reveal the Create a passkey button.
      createPasskey.classList.remove('hidden');
    } else {
      // If conditional UI isn't available, show a message.
      $('#message').innerText = 'This device does not support passkeys.';
    }
  } catch (e) {
    console.error(e);
  }
} else {
  // If WebAuthn isn't available, show a message.
  $('#message').innerText = 'This device does not support passkeys.';
}

// TODO: Add an ability to create a passkey: Render registered passkeys in a list.

async function renderCredentials() {
  const res = await _fetch('/auth/getKeys');
  const list = $('#list');
  const creds = html`${res.length > 0 ? html`
    <mdui-list>
      ${res.map(cred => html`
        <mdui-list-item>
          ${cred.name || 'Unnamed'}
          <mdui-button-icon data-cred-id="${cred.id}" data-name="${cred.name || 'Unnamed'}" @click="${rename}" icon="edit" slot="end-icon"></mdui-button-icon>
          <mdui-button-icon data-cred-id="${cred.id}" @click="${remove}" icon="delete" slot="end-icon"></mdui-button-icon>
        </mdui-list-item>`)}
    </mdui-list>` : html`
    <mdui-list>
      <mdui-list-item>No credentials found.</mdui-list-item>
    </mdui-list>`}`;
  render(creds, list);
};

renderCredentials();

// TODO: Add an ability to create a passkey: Create and register a passkey.

async function register() {
  try {
    // Start the loading UI.
    loading.start();
    // Start creating a passkey.
    await registerCredential();
    // Stop the loading UI.
    loading.stop();
    // Render the updated passkey list.
    renderCredentials();
  } catch (e) {
    // Stop the loading UI.
    loading.stop();
    // An InvalidStateError indicates that a passkey already exists on the device.
    if (e.name === 'InvalidStateError') {
      alert('A passkey already exists for this device.');
      // A NotAllowedError indicates the user canceled the operation.
    } else if (e.name === 'NotAllowedError') {
      return;
      // Show other errors in an alert.
    } else {
      alert(e.message);
      console.error(e);
    }
  }
};

createPasskey.addEventListener('click', register);

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

আপনি যদি এ পর্যন্ত সমস্ত ধাপ অনুসরণ করে থাকেন, তাহলে আপনি ওয়েবসাইটে পাসকি তৈরি, নিবন্ধন এবং প্রদর্শন করার ক্ষমতা বাস্তবায়ন করেছেন!

এটি চেষ্টা করতে, এই ধাপগুলো অনুসরণ করুন:

  1. সাইটটিতে একটি এলোমেলো ইউজারনেম ও পাসওয়ার্ড দিয়ে সাইন ইন করুন।
  2. পাসকি তৈরি করুন-এ ক্লিক করুন।
  3. ডিভাইসের স্ক্রিন লক দিয়ে আপনার পরিচয় যাচাই করুন।
  4. ওয়েব পেজের 'আপনার নিবন্ধিত পাসকিসমূহ' (Your registered passkeys) বিভাগে একটি পাসকি নিবন্ধিত এবং প্রদর্শিত হচ্ছে কিনা, তা নিশ্চিত করুন।

নিবন্ধিত পাসকিগুলো /home পেজে তালিকাভুক্ত করা হয়েছে।

নিবন্ধিত পাসকিগুলির নাম পরিবর্তন করুন এবং মুছে ফেলুন

আপনি তালিকায় থাকা নিবন্ধিত পাসকিগুলোর নাম পরিবর্তন বা মুছে ফেলতে পারবেন। কোডল্যাবের সাথে দেওয়া কোডে আপনি দেখে নিতে পারেন এটি কীভাবে কাজ করে।

ক্রোমে, আপনি ডেস্কটপে chrome://settings/passkeys থেকে অথবা অ্যান্ড্রয়েডে সেটিংসের পাসওয়ার্ড ম্যানেজার থেকে নিবন্ধিত পাসকিগুলো মুছে ফেলতে পারেন।

অন্যান্য প্ল্যাটফর্মে নিবন্ধিত পাসকিগুলির নাম পরিবর্তন এবং অপসারণ করার পদ্ধতি সম্পর্কে জানতে, সেই প্ল্যাটফর্মগুলির সংশ্লিষ্ট সাপোর্ট পেজগুলি দেখুন।

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

ব্যবহারকারীরা এখন একটি পাসকি তৈরি ও নিবন্ধন করতে পারবেন এবং আপনার ওয়েবসাইটে নিরাপদে প্রমাণীকরণের উপায় হিসেবে এটি ব্যবহার করার জন্য প্রস্তুত। এখন আপনাকে আপনার ওয়েবসাইটে একটি পাসকি প্রমাণীকরণ ব্যবস্থা যুক্ত করতে হবে।

authenticate() ফাংশনটি তৈরি করুন

  • public/client.js ফাইলে প্রাসঙ্গিক কমেন্টের পরে, authenticate() নামে একটি ফাংশন তৈরি করুন যা প্রথমে ব্যবহারকারীকে স্থানীয়ভাবে এবং তারপর সার্ভারের সাথে যাচাই করবে:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to authenticate with a passkey: Create the authenticate() function.
export async function authenticate() {

  // TODO: Add an ability to authenticate with a passkey: Obtain the challenge and other options from the server endpoint.

  // TODO: Add an ability to authenticate with a passkey: Locally verify the user and get a credential.

  // TODO: Add an ability to authenticate with a passkey: Verify the credential.

};

সার্ভার এন্ডপয়েন্ট থেকে চ্যালেঞ্জ এবং অন্যান্য বিকল্পগুলি সংগ্রহ করুন।

ব্যবহারকারীকে প্রমাণীকরণের জন্য অনুরোধ করার আগে, আপনাকে সার্ভার থেকে WebAuthn-এ পাস করার জন্য একটি চ্যালেঞ্জ সহ বিভিন্ন প্যারামিটার অনুরোধ করতে হবে।

  • authenticate() ফাংশনের বডিতে প্রাসঙ্গিক কমেন্টের পরে, সার্ভারে একটি POST রিকোয়েস্ট পাঠানোর জন্য _fetch() ফাংশনটি কল করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to authenticate with a passkey: Obtain the challenge and other options from the server endpoint.

// Base64URL decode the challenge.
const options = PublicKeyCredential.parseRequestOptionsFromJSON(_options);

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

{
  "challenge": *****,
  "rpId": "localhost",
  "allowCredentials": []
}

নিচের সারণিটি সম্পূর্ণ নয়, তবে এতে PublicKeyCredentialRequestOptions ডিকশনারির গুরুত্বপূর্ণ প্যারামিটারগুলো রয়েছে:

প্যারামিটার

বর্ণনা

challenge

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

rpId

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

allowCredentials

এই অথেনটিকেশনের জন্য যোগ্য অথেনটিকেটর খুঁজে বের করতে এই প্রপার্টিটি ব্যবহৃত হয়। ব্রাউজারকে একটি অ্যাকাউন্ট সিলেক্টর দেখাতে দেওয়ার জন্য একটি খালি অ্যারে পাস করুন অথবা এটিকে অনির্দিষ্ট রাখুন। allowCredentials কীভাবে কাজ করে সে সম্পর্কে আরও জানুন।

userVerification

একটি "preferred" মান সেট করুন অথবা এটি ডিফল্ট মান হওয়ায় বাদ দিন। এটি নির্দেশ করে যে ডিভাইসের স্ক্রিন লক ব্যবহার করে ব্যবহারকারী যাচাইকরণ "required" , "preferred" , নাকি "discouraged""preferred" মান সেট করলে, ডিভাইসটি সক্ষম হলে ব্যবহারকারী যাচাইকরণের জন্য অনুরোধ করা হয়। ব্যবহারকারী যাচাইকরণের আচরণ সম্পর্কে আরও জানুন।

স্থানীয়ভাবে ব্যবহারকারীকে যাচাই করুন এবং পরিচয়পত্র সংগ্রহ করুন।

  1. authenticate() ফাংশনের বডিতে প্রাসঙ্গিক কমেন্টের পরে, challenge প্যারামিটারটিকে আবার বাইনারিতে রূপান্তর করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to authenticate with a passkey: Locally verify the user and get a credential.
// Base64URL decode the challenge.
options.challenge = base64url.decode(options.challenge);
  1. ব্যবহারকারী প্রমাণীকরণের সময় একটি অ্যাকাউন্ট সিলেক্টর খুলতে allowCredentials প্যারামিটারে একটি খালি অ্যারে পাস করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// An empty allowCredentials array invokes an account selector by discoverable credentials.
options.allowCredentials = [];

অ্যাকাউন্ট সিলেক্টরটি পাসকি-র সাথে সংরক্ষিত ব্যবহারকারীর তথ্য ব্যবহার করে।

  1. mediation: 'conditional' অপশনটি সহ ` navigator.credentials.get() ` মেথডটি কল করুন:

পাবলিক/ক্লায়েন্ট.জেএস

// Invoke the WebAuthn get() method.
const cred = await navigator.credentials.get({
  publicKey: options,

  // Request a conditional UI.
  mediation: 'conditional'
});

এই অপশনটি ব্রাউজারকে ফর্ম অটোফিলের অংশ হিসেবে শর্তসাপেক্ষে পাসকি সাজেস্ট করতে নির্দেশ দেয়।

পরিচয়পত্র যাচাই করুন

ব্যবহারকারী স্থানীয়ভাবে তার পরিচয় যাচাই করার পর, আপনি একটি ক্রেডেনশিয়াল অবজেক্ট পাবেন, যেটিতে একটি স্বাক্ষর থাকবে যা আপনি সার্ভারে যাচাই করতে পারবেন।

নিম্নলিখিত কোড স্নিপেটে একটি PublicKeyCredential অবজেক্টের উদাহরণ অন্তর্ভুক্ত রয়েছে:

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

নিচের সারণিটি সম্পূর্ণ নয়, তবে এতে PublicKeyCredential অবজেক্টের গুরুত্বপূর্ণ প্যারামিটারগুলো রয়েছে:

প্যারামিটার

বর্ণনা

id

প্রমাণীকৃত পাসকি ক্রেডেনশিয়ালের Base64URL এনকোডেড আইডি।

rawId

ক্রেডেনশিয়াল আইডি-র একটি ArrayBuffer অবজেক্ট সংস্করণ।

response.clientDataJSON

ক্লায়েন্ট ডেটার একটি ArrayBuffer অবজেক্ট। এই ফিল্ডটিতে চ্যালেঞ্জ এবং অরিজিনের মতো তথ্য থাকে, যা RP সার্ভারকে যাচাই করতে হয়।

response.authenticatorData

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

response.signature

স্বাক্ষরটির একটি ArrayBuffer অবজেক্ট। এই মানটিই ক্রেডেনশিয়ালের মূল ভিত্তি এবং এটি সার্ভারে অবশ্যই যাচাই করতে হবে।

response.userHandle

একটি ArrayBuffer অবজেক্ট, যা তৈরির সময় সেট করা ইউজার আইডি ধারণ করে। যদি সার্ভারকে তার ব্যবহৃত আইডি ভ্যালুগুলো বেছে নিতে হয়, অথবা যদি ব্যাকএন্ড ক্রেডেনশিয়াল আইডিগুলোর উপর ইনডেক্স তৈরি করা এড়াতে চায়, তবে ক্রেডেনশিয়াল আইডির পরিবর্তে এই ভ্যালুটি ব্যবহার করা যেতে পারে।

authenticatorAttachment

এই ক্রেডেনশিয়ালটি স্থানীয় ডিভাইস থেকে এলে একটি "platform" স্ট্রিং রিটার্ন করে। অন্যথায় একটি "cross-platform" স্ট্রিং রিটার্ন করে, বিশেষত যখন ব্যবহারকারী সাইন ইন করার জন্য ফোন ব্যবহার করেন । যদি ব্যবহারকারীকে সাইন ইন করার জন্য ফোন ব্যবহার করতে হয়, তবে তাকে স্থানীয় ডিভাইসে একটি পাসকি তৈরি করতে বলুন।

সার্ভারে ক্রেডেনশিয়াল অবজেক্টটি পাঠাতে, এই ধাপগুলো অনুসরণ করুন:

  1. authenticate() ফাংশনের বডিতে প্রাসঙ্গিক কমেন্টের পরে, ক্রেডেনশিয়ালের বাইনারি প্যারামিটারগুলোকে এনকোড করুন, যাতে এটি সার্ভারে একটি স্ট্রিং হিসেবে পাঠানো যায়। এই কাজটি করার জন্য আপনি .toJSON() ব্যবহার করতে পারেন:

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to authenticate with a passkey: Verify the credential.
// Encode and serialize the `PublicKeyCredential`.
const credential = JSON.stringify(cred);
  1. অবজেক্টটি সার্ভারে পাঠান:

পাবলিক/ক্লায়েন্ট.জেএস

return await _fetch(`/auth/signinResponse`, credential);

যখন আপনি প্রোগ্রামটি চালান, তখন সার্ভার HTTP code 200 ফেরত দেয়, যা নির্দেশ করে যে পরিচয়পত্রটি যাচাই করা হয়েছে।

এখন আপনার কাছে সম্পূর্ণ authentication() ফাংশনটি রয়েছে!

এই অংশের সমাধান কোডটি পর্যালোচনা করুন।

পাবলিক/ক্লায়েন্ট.জেএস

// TODO: Add an ability to authenticate with a passkey: Create the authenticate() function.
export async function authenticate() {

  // TODO: Add an ability to authenticate with a passkey: Obtain the 
  challenge and other options from the server endpoint.
  const options = await _fetch('/auth/signinRequest');

  // TODO: Add an ability to authenticate with a passkey: Locally verify 
  the user and get a credential.
  // Base64URL decode the challenge.
  options.challenge = base64url.decode(options.challenge);

  // The empty allowCredentials array invokes an account selector 
  by discoverable credentials.
  options.allowCredentials = [];

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options,

    // Request a conditional UI.
    mediation: 'conditional'
  });

  // TODO: Add an ability to authenticate with a passkey: Verify the credential.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;

  // Base64URL encode some values.
  const clientDataJSON = base64url.encode(cred.response.clientDataJSON);
  const authenticatorData = 
  base64url.encode(cred.response.authenticatorData);
  const signature = base64url.encode(cred.response.signature);
  const userHandle = base64url.encode(cred.response.userHandle);

  credential.response = {
    clientDataJSON,
    authenticatorData,
    signature,
    userHandle,
  };

  return await _fetch(`/auth/signinResponse`, credential);
};

৬. ব্রাউজার অটোফিলে পাসকি যোগ করুন

ব্যবহারকারী যখন ফিরে আসবেন, আপনি চাইবেন তিনি যেন যতটা সম্ভব সহজে এবং নিরাপদে সাইন ইন করতে পারেন। আপনি যদি লগইন পেজে একটি ‘পাসকি দিয়ে সাইন ইন করুন ’ বাটন যোগ করেন, তাহলে ব্যবহারকারী বাটনটি টিপে, ব্রাউজারের অ্যাকাউন্ট সিলেক্টর থেকে একটি পাসকি বেছে নিয়ে এবং পরিচয় যাচাই করার জন্য স্ক্রিন লক ব্যবহার করতে পারবেন।

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

এখানেই কন্ডিশনাল UI কাজে আসে। কন্ডিশনাল UI হলো WebAuthn-এর একটি ফিচার, যার মাধ্যমে আপনি ফর্মের ইনপুট ফিল্ডকে পাসওয়ার্ডের পাশাপাশি অটোফিল আইটেম হিসেবে একটি পাসকি সাজেস্ট করার জন্য সেট করতে পারেন। যদি কোনো ব্যবহারকারী অটোফিল সাজেশনে থাকা কোনো পাসকিতে ট্যাপ করেন, তবে তাকে তার পরিচয় স্থানীয়ভাবে যাচাই করার জন্য ডিভাইসের স্ক্রিন লক ব্যবহার করতে বলা হয়। এটি একটি নির্বিঘ্ন ইউজার এক্সপেরিয়েন্স, কারণ এই কাজটি পাসওয়ার্ড-ভিত্তিক সাইন-ইনের মতোই।

d616744939063451.png

শর্তসাপেক্ষ UI সক্রিয় করুন

শর্তসাপেক্ষ UI চালু করতে, আপনাকে শুধু একটি ইনপুট ফিল্ডের autocomplete অ্যাট্রিবিউটে একটি webauthn টোকেন যোগ করতে হবে। টোকেনটি সেট করা হয়ে গেলে, আপনি mediation: 'conditional' স্ট্রিংটি সহ navigator.credentials.get() মেথডটি কল করে শর্তসাপেক্ষে স্ক্রিন লক UI চালু করতে পারবেন।

  • শর্তসাপেক্ষ UI সক্রিয় করতে, view/index.html ফাইলের প্রাসঙ্গিক কমেন্টের পরে বিদ্যমান ইউজারনেম ইনপুট ফিল্ডগুলিকে নিম্নলিখিত HTML দিয়ে প্রতিস্থাপন করুন:

ভিউ/ইনডেক্স.এইচটিএমএল

<!-- TODO: Add passkeys to the browser autofill: Enable conditional UI. -->
<mdui-text-field id="username" label="Username" name="username" autocomplete="username webauthn" autofocus></mdui-text-field>

বৈশিষ্ট্য সনাক্ত করুন, WebAuthn চালু করুন, এবং একটি শর্তসাপেক্ষ UI সক্রিয় করুন।

  1. view/index.html ফাইলে প্রাসঙ্গিক কমেন্টের পরে, বিদ্যমান import স্টেটমেন্টটি নিচের কোড দিয়ে প্রতিস্থাপন করুন:

ভিউ/ইনডেক্স.এইচটিএমএল

// TODO: Add passkeys to the browser autofill: Detect features, invoke WebAuthn, and enable a conditional UI.
import {
  $,
  _fetch,
  loading,
  authenticate 
} from "/client.js";

এই কোডটি আপনার পূর্বে প্রয়োগ করা authenticate() ফাংশনটি ইম্পোর্ট করে।

  1. নিশ্চিত করুন যে window.PulicKeyCredential অবজেক্টটি উপলব্ধ আছে এবং PublicKeyCredential.isConditionalMediationAvailable() মেথডটি একটি true ভ্যালু রিটার্ন করে, এবং তারপর authenticate() ফাংশনটি কল করুন:

ভিউ/ইনডেক্স.এইচটিএমএল

// TODO: Add passkeys to the browser autofill: Detect features, invoke WebAuthn, and enable a conditional UI.
if (window.PublicKeyCredential &&
    PublicKeyCredential.getClientCapabilities) {
  try {

    // Is conditional UI available in this browser?
      const capabilities = await PublicKeyCredential.getClientCapabilities();
      if (capabilities.conditionalGet) {

      // If conditional UI is available, invoke the authenticate() function.
      const user = await authenticate();
      if (user) {

        // Proceed only when authentication succeeds.
        $("#username").value = user.username;
        loading.start();
        location.href = "/home";
      } else {
        throw new Error("User not found.");
      }
    }
  } catch (e) {
    loading.stop();

    // A NotAllowedError indicates that the user canceled the operation.
    if (e.name !== "NotAllowedError") {
      console.error(e);
      alert(e.message);
    }
  }
}

এই অংশের সমাধান কোডটি পর্যালোচনা করুন।

ভিউ/ইনডেক্স.এইচটিএমএল

<!-- TODO: Add passkeys to the browser autofill: Enable conditional UI. -->
<mdui-text-field id="username" label="Username" name="username" autocomplete="username webauthn" autofocus></mdui-text-field>

ভিউ/ইনডেক্স.এইচটিএমএল

// TODO: Add passkeys to the browser autofill: Detect features, invoke WebAuthn, and enable a conditional UI.
import { 
  $, 
  _fetch, 
  loading, 
  authenticate 
} from '/client.js';

ভিউ/ইনডেক্স.এইচটিএমএল

// TODO: Add passkeys to the browser autofill: Detect features, invoke WebAuthn, and enable a conditional UI.        

// Is WebAuthn available on this browser?
if (window.PublicKeyCredential &&
    PublicKeyCredential.getClientCapabilities) {
  try {
    // Is conditional UI available in this browser?
    const capabilities = await PublicKeyCredential.getClientCapabilities();
    if (capabilities.conditionalGet) {
      // If conditional UI is available, invoke the authenticate() function.
      const user = await authenticate();
      if (user) {
        // Proceed only when authentication succeeds.
        $('#username').value = user.username;
        loading.start();
        location.href = '/home';
      } else {
        throw new Error('User not found.');
      }
    }
  } catch (e) {
    loading.stop();
    // A NotAllowedError indicates that the user canceled the operation.
    if (e.name !== 'NotAllowedError') {
      console.error(e);
      alert(e.message);
    }
  }
}

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

আপনি আপনার ওয়েবসাইটে পাসকি তৈরি, নিবন্ধন, প্রদর্শন এবং প্রমাণীকরণের ব্যবস্থা বাস্তবায়ন করেছেন।

এটি চেষ্টা করতে, এই ধাপগুলো অনুসরণ করুন:

  1. প্রিভিউ ট্যাবে যান।
  2. প্রয়োজন হলে সাইন আউট করুন।
  3. ইউজারনেম টেক্সট বক্সে ক্লিক করুন। একটি ডায়ালগ বক্স প্রদর্শিত হবে।
  4. যে অ্যাকাউন্ট দিয়ে আপনি সাইন ইন করতে চান, সেটি নির্বাচন করুন।
  5. ডিভাইসের স্ক্রিন লক দিয়ে আপনার পরিচয় যাচাই করুন। আপনাকে /home পেজে পুনঃনির্দেশিত করা হবে এবং সাইন ইন করা হবে।

একটি ডায়ালগ বক্স যা আপনাকে আপনার সংরক্ষিত পাসওয়ার্ড বা পাসকি দিয়ে আপনার পরিচয় যাচাই করতে অনুরোধ করে।

৭. অভিনন্দন!

আপনি এই কোডল্যাবটি সম্পন্ন করেছেন! আপনার কোনো প্রশ্ন থাকলে, FIDO-DEV মেইলিং লিস্টে অথবা StackOverflow-তে একটি passkey ট্যাগ ব্যবহার করে জিজ্ঞাসা করুন।

আরও জানুন