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

1. আপনি শুরু করার আগে

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

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

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

পূর্বশর্ত

আপনি কি শিখবেন

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

আপনি কি প্রয়োজন হবে

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

  • একটি Android ডিভাইস সহ Google Chrome যেটি Android 9 বা তার উচ্চতর সংস্করণ চালায়, বিশেষত একটি বায়োমেট্রিক সেন্সর দিয়ে৷
  • Windows 10 বা উচ্চতর সংস্করণে চলে এমন একটি Windows ডিভাইস সহ Chrome৷
  • IOS 16 বা উচ্চতর চালায় এমন iPhone সহ Safari 16 বা উচ্চতর, অথবা iPadOS 16 বা উচ্চতর চালায়।
  • Safari 16 বা উচ্চতর বা একটি Apple ডেস্কটপ ডিভাইস সহ Chrome যা macOS Ventura বা উচ্চতর চালায়।

2. সেট আপ করুন

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

প্রকল্প খুলুন

  1. গ্লিচে প্রকল্পটি খুলুন।
  2. গ্লিচ প্রজেক্টের জন্য রিমিক্সে ক্লিক করুন।
  3. গ্লিচের নীচে নেভিগেশন মেনুতে, একটি নতুন উইন্ডোতে পূর্বরূপ > পূর্বরূপ ক্লিক করুন। আপনার ব্রাউজারে আরেকটি ট্যাব খোলে।

Glitch-এর নীচে নেভিগেশন মেনুতে একটি নতুন উইন্ডোতে প্রিভিউ বোতাম

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

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

এই অবস্থায়, ব্যবহারকারীদের প্রতিবার লগ ইন করার সময় একটি পাসওয়ার্ড লিখতে হবে৷ আপনি এই ফর্মটিতে পাসকি সমর্থন যোগ করুন যাতে ব্যবহারকারীরা ডিভাইসের স্ক্রিন-লক কার্যকারিতা দিয়ে সাইন ইন করতে পারে৷ আপনি https://passkeys-codelab.glitch.me/ এ শেষ অবস্থা চেষ্টা করতে পারেন।

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

3. একটি পাসকি তৈরি করার ক্ষমতা যোগ করুন

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

পাসকি তৈরি করার সময় একটি পাসকি ব্যবহারকারী যাচাইকরণ ডায়ালগ উপস্থিত হয়।

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

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

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

পাবলিক/ক্লায়েন্ট। js

// 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 হল একটি ব্রাউজার API যা একজন ব্যবহারকারীকে একটি পাসকি তৈরি করতে এবং পাসকি দিয়ে ব্যবহারকারীকে প্রমাণীকরণ করতে দেয়। সৌভাগ্যবশত, আপনার কাছে ইতিমধ্যেই একটি সার্ভার এন্ডপয়েন্ট রয়েছে যা এই কোডল্যাবে এই ধরনের পরামিতিগুলির সাথে প্রতিক্রিয়া জানায়।

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

public/client.js

// 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 অবজেক্ট হতে হবে যাতে ব্যক্তিগত পরিচয় তথ্য, যেমন ই-মেইল ঠিকানা বা ব্যবহারকারীর নাম অন্তর্ভুক্ত থাকে না। একটি এলোমেলো, 16-বাইট মান প্রতি অ্যাকাউন্ট তৈরি করা ভাল কাজ করে।

user.name

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

user.displayName

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

rp.id

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

pubKeyCredParams

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

excludeCredentials

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

authenticatorSelection.authenticatorAttachment

একটি "platform" মান সেট করুন। এটি ইঙ্গিত দেয় যে আপনি একটি প্রমাণীকরণকারী চান যা প্ল্যাটফর্ম ডিভাইসে এম্বেড করা আছে যাতে ব্যবহারকারীকে একটি USB নিরাপত্তা কীর মতো কিছু সন্নিবেশ করার জন্য অনুরোধ করা হবে না।

authenticatorSelection.requireResidentKey

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

authenticatorSelection.userVerification

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

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

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

public/client.js

// TODO: Add an ability to create a passkey: Create a credential.
// Base64URL decode some values.
options.user.id = base64url.decode(options.user.id);
options.challenge = base64url.decode(options.challenge);

if (options.excludeCredentials) {
  for (let cred of options.excludeCredentials) {
    cred.id = base64url.decode(cred.id);
  }
}
  1. পরের লাইনে, authenticatorSelection.authenticatorAttachment কে "platform" এবং authenticatorSelection.requireResidentKey এ সেট করুন true এটি শুধুমাত্র একটি প্ল্যাটফর্ম প্রমাণীকরণকারী (ডিভাইসটি নিজেই) একটি আবিষ্কারযোগ্য শংসাপত্রের ক্ষমতা সহ ব্যবহারের অনুমতি দেয়।

public/client.js

// Use platform authenticator and discoverable credential.
options.authenticatorSelection = {
  authenticatorAttachment: 'platform',
  requireResidentKey: true
}
  1. পরের লাইনে, একটি শংসাপত্র তৈরি করতে navigator.credentials.create() পদ্ধতিতে কল করুন।

public/client.js

// 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. বেস64URL হিসাবে শংসাপত্রের বাইনারি প্যারামিটারগুলিকে এনকোড করুন যাতে এটি একটি স্ট্রিং হিসাবে সার্ভারে বিতরণ করা যায়:

public/client.js

// TODO: Add an ability to create a passkey: Register the credential to the server endpoint.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;

// The authenticatorAttachment string in the PublicKeyCredential object is a new addition in WebAuthn L3.
if (cred.authenticatorAttachment) {
  credential.authenticatorAttachment = cred.authenticatorAttachment;
}

// Base64URL encode some values.
const clientDataJSON = base64url.encode(cred.response.clientDataJSON);
const attestationObject = base64url.encode(cred.response.attestationObject);

// Obtain transports.
const transports = cred.response.getTransports ? cred.response.getTransports() : [];

credential.response = {
  clientDataJSON,
  attestationObject,
  transports
};
  1. পরবর্তী লাইনে, সার্ভারে বস্তুটি পাঠান:

public/client.js

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

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

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

এই বিভাগের জন্য সমাধান কোড পর্যালোচনা করুন

public/client.js

// 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 server endpoint.
  const options = await _fetch('/auth/registerRequest');
  
  // TODO: Add an ability to create a passkey: Create a credential.
  // Base64URL decode some values.

  options.user.id = base64url.decode(options.user.id);
  options.challenge = base64url.decode(options.challenge);

  if (options.excludeCredentials) {
    for (let cred of options.excludeCredentials) {
      cred.id = base64url.decode(cred.id);
    }
  }

  // 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.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;

  // The authenticatorAttachment string in the PublicKeyCredential object is a new addition in WebAuthn L3.
  if (cred.authenticatorAttachment) {
    credential.authenticatorAttachment = cred.authenticatorAttachment;
  }

  // Base64URL encode some values.
  const clientDataJSON = base64url.encode(cred.response.clientDataJSON);
  const attestationObject =  
  base64url.encode(cred.response.attestationObject);

  // Obtain transports.
  const transports = cred.response.getTransports ? 
  cred.response.getTransports() : [];

  credential.response = {
    clientDataJSON,
    attestationObject,
    transports
  };

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

4. পাসকি শংসাপত্র নিবন্ধন এবং পরিচালনা করতে একটি UI তৈরি করুন৷

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

/হোম পেজে তালিকাভুক্ত নিবন্ধিত পাসকি

স্থানধারক HTML যোগ করুন

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

views/home.html

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

div#list উপাদান হল তালিকার স্থানধারক।

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

পাসকিগুলি সমর্থন করে এমন ডিভাইসগুলির সাথে ব্যবহারকারীদের একটি পাসকি তৈরি করার বিকল্পটি দেখানোর জন্য, আপনাকে প্রথমে WebAuthn উপলব্ধ কিনা তা পরীক্ষা করতে হবে৷ যদি তাই হয়, তাহলে আপনাকে একটি পাসকি তৈরি বোতামটি দেখানোর জন্য hidden ক্লাসটি সরাতে হবে।

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

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

views/home.html

// 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. শর্তসাপেক্ষের মূল অংশে, ডিভাইসটি একটি পাসকি তৈরি করতে পারে কিনা তা পরীক্ষা করুন এবং তারপরে একটি ফর্ম স্বতঃপূরণে পাসকি প্রস্তাবিত হতে পারে কিনা তা পরীক্ষা করুন।

views/home.html

try {
  const results = await Promise.all([

    // Is platform authenticator available in this browser?
    PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(),

    // Is conditional UI available in this browser?
    PublicKeyCredential.isConditionalMediationAvailable()
  ]);
  1. সমস্ত শর্ত পূরণ হলে, একটি পাসকি তৈরি করতে বোতামটি দেখান। অন্যথায়, একটি সতর্কতা বার্তা দেখান।

views/home.html

    if (results.every(r => r === 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.';
}

একটি তালিকায় নিবন্ধিত পাসকি রেন্ডার করুন

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

views/home.html

// 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`
    <mwc-list>
      ${res.map(cred => html`
        <mwc-list-item>
          <div class="list-item">
            <div class="entity-name">
              <span>${cred.name || 'Unnamed' }</span>
          </div>
          <div class="buttons">
            <mwc-icon-button data-cred-id="${cred.id}"  
            data-name="${cred.name || 'Unnamed' }" @click="${rename}"  
            icon="edit"></mwc-icon-button>
            <mwc-icon-button data-cred-id="${cred.id}" @click="${remove}" 
            icon="delete"></mwc-icon-button>
          </div>
         </div>
      </mwc-list-item>`)}
  </mwc-list>` : html`
  <mwc-list>
    <mwc-list-item>No credentials found.</mwc-list-item>
  </mwc-list>`}`;
  render(creds, list);
};
  1. পরের লাইনে, renderCredentials() ফাংশনটি চালু করুন যাতে ব্যবহারকারী /home পেজে ল্যান্ড করার সাথে সাথে রেজিস্টার্ড পাসকি প্রদর্শন করতে শুরু করে।

views/home.html

renderCredentials();

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

একটি পাসকি তৈরি এবং নিবন্ধন করতে, আপনাকে registerCredential() ফাংশনটি কল করতে হবে যা আপনি আগে প্রয়োগ করেছেন৷

আপনি যখন একটি পাসকি তৈরি করুন বোতামে ক্লিক করেন তখন registerCredential() ফাংশনটি ট্রিগার করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. স্থানধারক HTML এর পরে ফাইলটিতে, নিম্নলিখিত import বিবৃতিটি খুঁজুন:

views/home.html

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

views/home.html

// 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() কল করে৷ এটি স্পষ্ট করে যে ব্রাউজার একটি পাসকি তৈরি করে এবং কিছু ভুল হলে একটি ত্রুটি বার্তা দেখায়।

views/home.html

// 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 ত্রুটিও ফেলে। আপনি নীরবে এই ক্ষেত্রে এটি উপেক্ষা.

views/home.html

  } 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() ফাংশনের পরে লাইনে, একটি পাসকি বোতাম তৈরি করার জন্য একটি click ইভেন্টে register() ফাংশন সংযুক্ত করুন।

views/home.html

createPasskey.addEventListener('click', register);

এই বিভাগের জন্য সমাধান কোড পর্যালোচনা করুন

views/home.html

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

views/home.html

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

views/home.html

// 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) {
  try {
    const results = await Promise.all([

      // Is platform authenticator available in this browser?
      PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(),

      // Is conditional UI available in this browser?
      PublicKeyCredential.isConditionalMediationAvailable()
    ]);
    if (results.every(r => r === 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`
  <mwc-list>
    ${res.map(cred => html`
      <mwc-list-item>
        <div class="list-item">
          <div class="entity-name">
            <span>${cred.name || 'Unnamed' }</span>
          </div>
          <div class="buttons">
            <mwc-icon-button data-cred-id="${cred.id}" data-name="${cred.name || 'Unnamed' }" @click="${rename}" icon="edit"></mwc-icon-button>
            <mwc-icon-button data-cred-id="${cred.id}" @click="${remove}" icon="delete"></mwc-icon-button>
          </div>
        </div>
      </mwc-list-item>`)}
  </mwc-list>` : html`
  <mwc-list>
    <mwc-list-item>No credentials found.</mwc-list-item>
  </mwc-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 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);
    }
  }
};

createPasskey.addEventListener('click', register);

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

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

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

  1. পূর্বরূপ ট্যাবে, একটি এলোমেলো ব্যবহারকারীর নাম এবং পাসওয়ার্ড দিয়ে সাইন ইন করুন৷
  2. একটি পাসকি তৈরি করুন ক্লিক করুন।
  3. ডিভাইসের স্ক্রিন লক দিয়ে আপনার পরিচয় যাচাই করুন।
  4. নিশ্চিত করুন যে একটি পাসকি নিবন্ধিত এবং ওয়েব পৃষ্ঠার আপনার নিবন্ধিত পাসকি বিভাগের অধীনে প্রদর্শিত হয়েছে৷

/হোম পেজে তালিকাভুক্ত নিবন্ধিত পাসকি।

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

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

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

অন্যান্য প্ল্যাটফর্মগুলিতে নিবন্ধিত পাসকিগুলি কীভাবে পুনঃনামকরণ এবং সরানো যায় সে সম্পর্কে তথ্যের জন্য, সেই প্ল্যাটফর্মগুলির জন্য সংশ্লিষ্ট সমর্থন পৃষ্ঠাগুলি দেখুন৷

5. একটি পাসকি দিয়ে প্রমাণীকরণ করার ক্ষমতা যোগ করুন

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

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

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

public/client.js

// 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() ফাংশনটিতে কল করুন:

public/client.js

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

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

{
  "challenge": *****,
  "rpId": "passkeys-codelab.glitch.me",
  "allowCredentials": []
}

নিম্নলিখিত সারণীটি সম্পূর্ণ নয়, তবে এতে PublicKeyCredentialRequestOptions অভিধানে গুরুত্বপূর্ণ প্যারামিটার রয়েছে:

পরামিতি

বর্ণনা

challenge

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

rpId

একটি RP ID হল একটি ডোমেইন। একটি ওয়েবসাইট তার ডোমেন বা একটি নিবন্ধনযোগ্য প্রত্যয় নির্দিষ্ট করতে পারে। এই মানটি অবশ্যই পাসকি তৈরি করার সময় ব্যবহৃত rp.id প্যারামিটারের সাথে মেলে।

allowCredentials

এই প্রমাণীকরণের জন্য যোগ্য প্রমাণীকরণকারীদের খুঁজে পেতে এই সম্পত্তি ব্যবহার করা হয়। একটি খালি অ্যারে পাস করুন বা ব্রাউজারটিকে একটি অ্যাকাউন্ট নির্বাচক দেখানোর জন্য এটি অনির্দিষ্ট রেখে দিন।

userVerification

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

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

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

public/client.js

// 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 প্যারামিটারে একটি খালি অ্যারে পাস করুন:

public/client.js

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

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

  1. একটি মধ্যস্থতা সহ navigator.credentials.get() পদ্ধতিতে কল করুন mediation: 'conditional' বিকল্প:

public/client.js

// 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 এনকোড করা ID।

rawId

শংসাপত্র আইডির একটি ArrayBuffer অবজেক্ট সংস্করণ।

response.clientDataJSON

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

response.authenticatorData

প্রমাণীকরণকারী ডেটার একটি ArrayBuffer অবজেক্ট। এই ক্ষেত্রটিতে RP ID এর মত তথ্য রয়েছে।

response.signature

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

response.userHandle

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

authenticatorAttachment

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

সার্ভারে শংসাপত্রের বস্তু পাঠাতে, এই পদক্ষেপগুলি অনুসরণ করুন:

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

public/client.js

// 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,
};
  1. সার্ভারে বস্তুটি পাঠান:

public/client.js

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

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

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

এই বিভাগের জন্য সমাধান কোড পর্যালোচনা করুন

public/client.js

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

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

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

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

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

একটি পাসকি ফর্ম অটোফিলের অংশ হিসাবে প্রস্তাবিত৷

একটি শর্তসাপেক্ষ UI সক্ষম করুন৷

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

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

view/index.html

<!-- TODO: Add passkeys to the browser autofill: Enable conditional UI. -->
<input
  type="text"
  id="username"
  class="mdc-text-field__input"
  aria-labelledby="username-label"
  name="username"
  autocomplete="username webauthn"
  autofocus />

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

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

view/index.html

// 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() ফাংশনটি কল করুন:

view/index.html

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

    // Is conditional UI available in this browser?
    const cma =
      await PublicKeyCredential.isConditionalMediationAvailable();
    if (cma) {

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

এই বিভাগের জন্য সমাধান কোড পর্যালোচনা করুন

view/index.html

<!-- TODO: Add passkeys to the browser autofill: Enable conditional UI. -->
<input
  type="text"
  id="username"
  class="mdc-text-field__input"
  aria-labelledby="username-label"
  name="username"
  autocomplete="username webauthn"
  autofocus 
/>

view/index.html

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

view/index.html

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

    // Is a conditional UI available in this browser?
    const cma= await PublicKeyCredential.isConditionalMediationAvailable();
    if (cma) {

      // If a 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 পেজে পুনঃনির্দেশিত করা হয়েছে এবং সাইন ইন করা হয়েছে৷

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

7. অভিনন্দন!

আপনি এই কোডল্যাব শেষ! আপনার যদি কোনো প্রশ্ন থাকে, তাহলে তাদেরকে FIDO-DEV মেলিং লিস্টে বা স্ট্যাকওভারফ্লোতে একটি passkey ট্যাগ দিয়ে জিজ্ঞাসা করুন।

আরও জানুন