वेब ऐप्लिकेशन में फ़ॉर्म में अपने-आप जानकारी भरने की सुविधा के साथ पासकी लागू करना

1. शुरू करने से पहले

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

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

  • यह बटन, उपयोगकर्ता के साइन इन करने के बाद पासकी बनाता है.
  • यूज़र इंटरफ़ेस (यूआई), जिसमें रजिस्टर की गई पासकी की सूची दिखती है.
  • मौजूदा साइन-इन फ़ॉर्म, जिसकी मदद से उपयोगकर्ता, रजिस्टर की गई पासकी से साइन इन कर सकते हैं. इसके लिए, उन्हें फ़ॉर्म में अपने-आप भरने की सुविधा का इस्तेमाल करना होगा.

ज़रूरी शर्तें

  • JavaScript की बुनियादी जानकारी
  • Web Authentication API (WebAuthn) के बारे में बुनियादी जानकारी

आपको क्या सीखने को मिलेगा

  • पासकी बनाने का तरीका.
  • पासकी की मदद से उपयोगकर्ताओं की पुष्टि करने का तरीका.
  • किसी फ़ॉर्म को साइन-इन करने के विकल्प के तौर पर पासकी का सुझाव देने की अनुमति देने का तरीका.

2. सेट अप करें

इस कोडलैब में, GitHub से एक अधूरा डेमो ऐप्लिकेशन क्लोन किया जाएगा. इसके बाद, पासकी की सुविधा को लागू किया जाएगा.

प्रोजेक्ट का क्लोन बनाना

  1. GitHub पर प्रोजेक्ट खोलें.
  2. प्रोजेक्ट को क्लोन करें या डाउनलोड करें.

ac587c53b746785a.png

प्रोजेक्ट चलाना

  1. टर्मिनल खोलें और डायरेक्ट्री बदलने के लिए cd start का इस्तेमाल करें.
  2. प्रोजेक्ट की डिपेंडेंसी इंस्टॉल करने के लिए, npm install चलाएं.
  3. npm run build && IS_LOCAL=1 npm run start की मदद से प्रोजेक्ट बनाएं और उसे चलाएं.
  4. अपने ब्राउज़र में http://localhost:8080/ खोलें.

वेबसाइट की शुरुआती स्थिति की जांच करना

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

इस स्थिति में, उपयोगकर्ताओं को हर बार लॉग इन करते समय पासवर्ड डालना होगा. आपने इस फ़ॉर्म में पासकी की सुविधा जोड़ी है, ताकि उपयोगकर्ता डिवाइस के स्क्रीन लॉक की सुविधा का इस्तेमाल करके साइन इन कर सकें.

पासकी के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, पासकी कैसे काम करती हैं? लेख पढ़ें.

3. पासकी बनाने की सुविधा जोड़ना

उपयोगकर्ताओं को पासकी की मदद से पुष्टि करने की सुविधा देने के लिए, आपको उन्हें पासकी बनाने और रजिस्टर करने की सुविधा देनी होगी. साथ ही, सर्वर पर इसकी सार्वजनिक कुंजी सेव करनी होगी.

9b84dbaec66afe9c.png

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

registerCredential() फ़ंक्शन बनाना

  1. अपनी पसंद के कोड एडिटर में, start डायरेक्ट्री खोलें.
  2. public/client.js फ़ाइल पर जाएं. इसके बाद, आखिर तक स्क्रोल करें.
  3. ज़रूरी टिप्पणी के बाद, यह 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 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() फ़ंक्शन के मुख्य हिस्से में, काम की टिप्पणी के बाद यह कोड जोड़ें:

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 स्पेसिफ़िकेशन का हिस्सा नहीं है. हालांकि, इस कोडलैब का सर्वर, PublicKeyCredentialCreationOptions डिक्शनरी के जितना हो सके उतना मिलता-जुलता JSON दिखाता है. यह डिक्शनरी, WebAuthn navigator.credentials.create() API को पास की जाती है.

यहां दी गई टेबल में PublicKeyCredentialCreationOptions डिक्शनरी के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें ज़रूरी पैरामीटर शामिल हैं:

पैरामीटर

जानकारी

challenge

यह रजिस्ट्रेशन के लिए, ArrayBuffer ऑब्जेक्ट में सर्वर से जनरेट किया गया चैलेंज है. यह ज़रूरी है, लेकिन रजिस्ट्रेशन के दौरान इसका इस्तेमाल नहीं किया जाता. हालांकि, अटेस्टेशन के दौरान इसका इस्तेमाल किया जाता है. यह एक ऐडवांस विषय है, जिसे इस कोडलैब में शामिल नहीं किया गया है.

user.id

उपयोगकर्ता का यूनीक आईडी. यह वैल्यू, एक ArrayBuffer ऑब्जेक्ट होनी चाहिए. इसमें व्यक्तिगत पहचान से जुड़ी जानकारी शामिल नहीं होनी चाहिए. जैसे, ईमेल पते या उपयोगकर्ता नाम. हर खाते के लिए, किसी भी क्रम में जनरेट की गई 16-बाइट की वैल्यू का इस्तेमाल किया जा सकता है.

user.name

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

user.displayName

यह फ़ील्ड, खाते का आसान नाम है. इसे भरना ज़रूरी नहीं है. यह यूनीक होना ज़रूरी नहीं है. यह उपयोगकर्ता का चुना हुआ नाम हो सकता है. अगर आपकी वेबसाइट पर इस एट्रिब्यूट के लिए कोई सही वैल्यू मौजूद नहीं है, तो एक खाली स्ट्रिंग पास करें. यह जानकारी, ब्राउज़र के हिसाब से खाता चुनने वाले टूल पर दिख सकती है.

rp.id

रिलाइंग पार्टी (आरपी) आईडी एक डोमेन होता है. कोई वेबसाइट, अपना डोमेन या रजिस्टर किया जा सकने वाला सफ़िक्स तय कर सकती है. उदाहरण के लिए, अगर किसी आरपी का ऑरिजिन https://login.example.com:1337 है, तो आरपी आईडी login.example.com या example.com हो सकता है. अगर आरपी आईडी को example.com के तौर पर सेट किया जाता है, तो उपयोगकर्ता login.example.com या example.com के किसी अन्य सबडोमेन पर पुष्टि कर सकता है.

pubKeyCredParams

इस फ़ील्ड में, आरपी के साथ काम करने वाले सार्वजनिक कुंजी एल्गोरिदम के बारे में बताया जाता है. हमारा सुझाव है कि इसे [{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}] पर सेट करें. इससे पता चलता है कि P-256 और RSA PKCS#1 के साथ ECDSA का इस्तेमाल किया जा सकता है. साथ ही, इन दोनों का इस्तेमाल करने से पूरा कवरेज मिलता है.

excludeCredentials

यह कुकी, पहले से रजिस्टर किए गए क्रेडेंशियल आईडी की सूची उपलब्ध कराती है. इससे एक ही डिवाइस को दो बार रजिस्टर करने से रोका जा सकता है. अगर यह जानकारी दी गई है, तो transports सदस्य में, हर क्रेडेंशियल के रजिस्ट्रेशन के दौरान getTransports() फ़ंक्शन को कॉल करने का नतीजा शामिल होना चाहिए. अगर पहले से कोई पासकी मौजूद है, तो नई पासकी बनाने से रोकने के तरीके के बारे में हमारे दस्तावेज़ में ज़्यादा जानें.

authenticatorSelection.authenticatorAttachment

इसे "platform" वैल्यू पर सेट करें. इससे पता चलता है कि आपको प्लैटफ़ॉर्म डिवाइस में एम्बेड किया गया एक ऐसा पुष्टि करने वाला ऐप्लिकेशन चाहिए जिससे उपयोगकर्ता को यूएसबी सुरक्षा कुंजी जैसी कोई चीज़ डालने के लिए न कहा जाए.

authenticatorSelection.requireResidentKey

इसे बूलियन true वैल्यू पर सेट करें. डिस्कवर की जा सकने वाली क्रेडेंशियल (रेज़िडेंट कुंजी) का इस्तेमाल किया जा सकता है. इसके लिए, सर्वर को क्रेडेंशियल का आईडी देने की ज़रूरत नहीं होती. इसलिए, यह ऑटोमैटिक तरीके से भरने की सुविधा के साथ काम करता है. ज़्यादा जानने के लिए, डिस्कवर किए जा सकने वाले क्रेडेंशियल के बारे में ज़्यादा जानकारी पढ़ें.

authenticatorSelection.userVerification

इसे "preferred" वैल्यू पर सेट करें या इसे शामिल न करें, क्योंकि यह डिफ़ॉल्ट वैल्यू है. इससे पता चलता है कि डिवाइस के स्क्रीन लॉक का इस्तेमाल करके, उपयोगकर्ता की पुष्टि करने की सुविधा "required", "preferred" या "discouraged" है. "preferred" वैल्यू पर सेट करने से, डिवाइस के उपलब्ध होने पर उपयोगकर्ता की पुष्टि करने का अनुरोध किया जाता है. ज़्यादा जानने के लिए, उपयोगकर्ता की पुष्टि करने के बारे में ज़्यादा जानकारी लेख पढ़ें.

क्रेडेंशियल बनाना

  1. registerCredential() फ़ंक्शन के मुख्य हिस्से में, काम की टिप्पणी के बाद, Base64URL का इस्तेमाल करके एन्कोड किए गए कुछ पैरामीटर को वापस बाइनरी में बदलें. खास तौर पर, user.id और challenge स्ट्रिंग, और excludeCredentials कलेक्शन में शामिल id स्ट्रिंग के इंस्टेंस. PublicKeyCredential.parseCreationOptionsFromJSON() फ़ंक्शन का इस्तेमाल करके ऐसा किया जा सकता है:

public/client.js

// 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 पर सेट करें. इससे सिर्फ़ ऐसे प्लैटफ़ॉर्म ऑथेंटिकेटर (डिवाइस) का इस्तेमाल किया जा सकता है जिसमें क्रेडेंशियल का पता लगाने की सुविधा हो.

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 कोड में बदला गया अटेस्टेशन ऑब्जेक्ट. इसमें आरपी आईडी, फ़्लैग, और सार्वजनिक कुंजी जैसी अहम जानकारी होती है.

response.transports

डिवाइस पर काम करने वाले ट्रांसपोर्ट की सूची: "internal" का मतलब है कि डिवाइस पर पासकी काम करती है. "hybrid" का मतलब है कि यह किसी दूसरे डिवाइस पर पुष्टि करने की सुविधा के साथ भी काम करता है.

authenticatorAttachment

पासकी की सुविधा वाले डिवाइस पर यह क्रेडेंशियल बनाए जाने पर, "platform" दिखाता है.

क्रेडेंशियल ऑब्जेक्ट को सर्वर पर भेजने के लिए, यह तरीका अपनाएं:

  1. क्रेडेंशियल के बाइनरी पैरामीटर को Base64URL के तौर पर एन्कोड करें, ताकि इसे सर्वर को स्ट्रिंग के तौर पर डिलीवर किया जा सके. इसके लिए, .toJSON() का इस्तेमाल किया जा सकता है:

public/client.js

// 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. अगली लाइन में, ऑब्जेक्ट को सर्वर पर भेजें:

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

4. पासकी क्रेडेंशियल रजिस्टर करने और उन्हें मैनेज करने के लिए यूज़र इंटरफ़ेस (यूआई) बनाना

registerCredential() फ़ंक्शन उपलब्ध होने के बाद, आपको इसे चालू करने के लिए एक बटन की ज़रूरत होगी. साथ ही, आपको रजिस्टर की गई पासकी की सूची दिखानी होगी.

bfa4e7cdda47669e.png

प्लेसहोल्डर एचटीएमएल जोड़ना

  1. एडिटर में, views/home.html फ़ाइल पर जाएं.
  2. ज़रूरी टिप्पणी के बाद, यूज़र इंटरफ़ेस (यूआई) का ऐसा प्लेसहोल्डर जोड़ें जो पासकी रजिस्टर करने के लिए बटन और पासकी की सूची दिखाता हो:

views/home.html

​​<!-- 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 उपलब्ध है या नहीं. अगर ऐसा है, तो पासकी बनाएं बटन दिखाने के लिए, आपको 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 capabilities = await PublicKeyCredential.getClientCapabilities();
    // Is conditional UI available in this browser?
    if (capabilities.conditionalGet === true &&
        capabilities.passkeyPlatformAuthenticator === true) {
  1. अगर सभी शर्तें पूरी होती हैं, तो पासकी बनाने का बटन दिखाएं. ऐसा न होने पर, चेतावनी वाला मैसेज दिखाएं.

views/home.html

      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 = 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. अगली लाइन में, renderCredentials() फ़ंक्शन को शुरू करें, ताकि उपयोगकर्ता के /home पेज पर पहुंचते ही, रजिस्टर की गई पासकी दिखें.

views/home.html

renderCredentials();

पासकी बनाना और रजिस्टर करना

पासकी बनाने और रजिस्टर करने के लिए, आपको registerCredential() फ़ंक्शन को कॉल करना होगा. इसे आपने पहले लागू किया था.

पासकी बनाएं बटन पर क्लिक करने पर, registerCredential() फ़ंक्शन को ट्रिगर करने के लिए, यह तरीका अपनाएं:

  1. प्लेसहोल्डर एचटीएमएल के बाद, फ़ाइल में यह 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() फ़ंक्शन और लोडिंग यूज़र इंटरफ़ेस (यूआई) को शुरू करता है. साथ ही, रजिस्ट्रेशन के बाद 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() फ़ंक्शन के बाद वाली लाइन में, register() फ़ंक्शन को पासकी बनाएं बटन के लिए click इवेंट से अटैच करें.

views/home.html

createPasskey.addEventListener('click', register);

इस सेक्शन के लिए, समाधान के कोड की समीक्षा करें

views/home.html

<!-- 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>

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

// 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. पुष्टि करें कि वेब पेज के आपकी रजिस्टर की गई पासकी सेक्शन में, पासकी रजिस्टर की गई हो और दिख रही हो.

/home पेज पर रजिस्टर की गई पासकी की सूची.

रजिस्टर की गई पासकी का नाम बदलना और उन्हें हटाना

आपके पास सूची में मौजूद, रजिस्टर की गई पासकी का नाम बदलने या उन्हें मिटाने का विकल्प होना चाहिए. कोडलैब के साथ आने वाले कोड में, यह देखा जा सकता है कि यह कैसे काम करता है.

Chrome में, डेस्कटॉप पर chrome://settings/passkeys पर जाकर या Android पर सेटिंग में मौजूद Password Manager में जाकर, रजिस्टर की गई पासकी हटाई जा सकती हैं.

दूसरे प्लैटफ़ॉर्म पर रजिस्टर की गई पासकी का नाम बदलने और उन्हें हटाने के बारे में जानकारी पाने के लिए, उन प्लैटफ़ॉर्म के सहायता पेज देखें.

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() फ़ंक्शन के मुख्य हिस्से में, काम की टिप्पणी के बाद, _fetch() फ़ंक्शन को कॉल करें. इससे सर्वर को POST अनुरोध भेजा जा सकेगा:

public/client.js

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

इस कोडलैब का सर्वर, ऐसे JSON को दिखाता है जो PublicKeyCredentialRequestOptions डिक्शनरी के जितना हो सके उतना मिलता-जुलता हो. इस डिक्शनरी को WebAuthn navigator.credentials.get() API को पास किया जाता है. नीचे दिए गए कोड स्निपेट में, उदाहरण के तौर पर वे विकल्प दिए गए हैं जो आपको मिलने चाहिए:

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

यहां दी गई टेबल में PublicKeyCredentialRequestOptions डिक्शनरी के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें ज़रूरी पैरामीटर शामिल हैं:

पैरामीटर

जानकारी

challenge

ArrayBuffer ऑब्जेक्ट में सर्वर से जनरेट किया गया चैलेंज. यह रीप्ले अटैक को रोकने के लिए ज़रूरी है. जवाब में एक ही चैलेंज को दो बार स्वीकार न करें.

rpId

आरपी आईडी एक डोमेन होता है. कोई वेबसाइट, अपना डोमेन या रजिस्टर किया जा सकने वाला सफ़िक्स तय कर सकती है. यह वैल्यू, पासकी बनाते समय इस्तेमाल किए गए rp.id पैरामीटर से मेल खानी चाहिए.

allowCredentials

इस प्रॉपर्टी का इस्तेमाल, पुष्टि करने के लिए ज़रूरी शर्तें पूरी करने वाले पुष्टि करने वाले लोगों को ढूंढने के लिए किया जाता है. ब्राउज़र को खाता चुनने वाला टूल दिखाने की अनुमति देने के लिए, एक खाली कलेक्शन पास करें या इसे तय न करें. इस बारे में ज़्यादा जानें कि 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. mediation: 'conditional' विकल्प के साथ navigator.credentials.get() वाले तरीके को कॉल करें:

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 कोड में बदला गया आईडी.

rawId

ArrayBuffer ऑब्जेक्ट, क्रेडेंशियल आईडी का वर्शन होता है.

response.clientDataJSON

क्लाइंट के डेटा का ArrayBuffer ऑब्जेक्ट. इस फ़ील्ड में ऐसी जानकारी होती है जिसकी पुष्टि आरपी सर्वर को करनी होती है. जैसे, चुनौती और ऑरिजिन.

response.authenticatorData

पुष्टि करने वाले व्यक्ति के डेटा का ArrayBuffer ऑब्जेक्ट. इस फ़ील्ड में आरपी आईडी जैसी जानकारी होती है.

response.signature

हस्ताक्षर का ArrayBuffer ऑब्जेक्ट. यह वैल्यू, क्रेडेंशियल का मुख्य हिस्सा होती है. इसकी पुष्टि सर्वर पर की जानी चाहिए.

response.userHandle

यह एक ArrayBuffer ऑब्जेक्ट होता है. इसमें उपयोगकर्ता का वह आईडी होता है जो खाता बनाते समय सेट किया गया था. अगर सर्वर को उन आईडी वैल्यू को चुनना है जिनका वह इस्तेमाल करता है या बैकएंड, क्रेडेंशियल आईडी पर इंडेक्स बनाने से बचना चाहता है, तो इस वैल्यू का इस्तेमाल क्रेडेंशियल आईडी के बजाय किया जा सकता है.

authenticatorAttachment

जब यह क्रेडेंशियल लोकल डिवाइस से आता है, तो यह फ़ंक्शन "platform" स्ट्रिंग दिखाता है. इसके अलावा, यह "cross-platform" स्ट्रिंग दिखाता है. खास तौर पर, तब जब उपयोगकर्ता साइन इन करने के लिए फ़ोन का इस्तेमाल करता है. अगर उपयोगकर्ता को साइन इन करने के लिए फ़ोन का इस्तेमाल करना है, तो उसे स्थानीय डिवाइस पर पासकी बनाने के लिए कहें.

क्रेडेंशियल ऑब्जेक्ट को सर्वर पर भेजने के लिए, यह तरीका अपनाएं:

  1. authenticate() फ़ंक्शन के मुख्य हिस्से में, काम की टिप्पणी के बाद क्रेडेंशियल के बाइनरी पैरामीटर को कोड में बदलें, ताकि इसे सर्वर को स्ट्रिंग के तौर पर डिलीवर किया जा सके. इसके लिए, .toJSON() का इस्तेमाल किया जा सकता है:

public/client.js

// TODO: Add an ability to authenticate with a passkey: Verify the credential.
// Encode and serialize the `PublicKeyCredential`.
const credential = JSON.stringify(cred);
  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. ब्राउज़र में अपने-आप भरने की सुविधा के लिए पासकी जोड़ना

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

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

ऐसे में, शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) काम आता है. कंडीशनल यूज़र इंटरफ़ेस (यूआई), WebAuthn की एक सुविधा है. इसमें फ़ॉर्म के इनपुट फ़ील्ड को इस तरह से बनाया जा सकता है कि वह पासवर्ड के साथ-साथ, पासकी को भी अपने-आप भरने वाले आइटम के तौर पर सुझाए. अगर कोई व्यक्ति, अपने-आप भरने की सुविधा के सुझावों में मौजूद किसी पासकी पर टैप करता है, तो उसे डिवाइस के स्क्रीन लॉक का इस्तेमाल करके, स्थानीय तौर पर अपनी पहचान की पुष्टि करने के लिए कहा जाता है. इससे उपयोगकर्ताओं को बेहतर अनुभव मिलता है, क्योंकि उपयोगकर्ता की कार्रवाई, पासवर्ड के ज़रिए साइन-इन करने की कार्रवाई से मिलती-जुलती होती है.

d616744939063451.png

शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) चालू करना

शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) को चालू करने के लिए, आपको सिर्फ़ इनपुट फ़ील्ड के autocomplete एट्रिब्यूट में webauthn टोकन जोड़ना होगा. टोकन सेट होने पर, mediation: 'conditional' स्ट्रिंग के साथ navigator.credentials.get() तरीके को कॉल किया जा सकता है. इससे स्क्रीन लॉक यूज़र इंटरफ़ेस (यूआई) को शर्तों के हिसाब से ट्रिगर किया जा सकता है.

  • शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) चालू करने के लिए, view/index.html फ़ाइल में मौजूद काम की टिप्पणी के बाद, मौजूदा उपयोगकर्ता नाम वाले इनपुट फ़ील्ड को इस एचटीएमएल से बदलें:

view/index.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 को चालू करना, और शर्तों के हिसाब से यूज़र इंटरफ़ेस (यूआई) को चालू करना

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

इस सेक्शन के लिए, समाधान के कोड की समीक्षा करें

view/index.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>

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 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 पेज पर रीडायरेक्ट कर दिया जाएगा और आपने साइन इन कर लिया होगा.

एक डायलॉग बॉक्स, जिसमें आपको सेव किए गए पासवर्ड या पासकी की मदद से अपनी पहचान की पुष्टि करने के लिए कहा जाता है.

7. बधाई हो!

आपने यह कोडलैब पूरा कर लिया है! अगर आपका कोई सवाल है, तो उसे FIDO-DEV mailing list पर पूछें या StackOverflow पर passkey टैग के साथ पूछें.

ज़्यादा जानें