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

प्रोजेक्ट चलाना
- टर्मिनल खोलें और डायरेक्ट्री बदलने के लिए
cd startका इस्तेमाल करें. - प्रोजेक्ट की डिपेंडेंसी इंस्टॉल करने के लिए,
npm installचलाएं. npm run build && IS_LOCAL=1 npm run startकी मदद से प्रोजेक्ट बनाएं और उसे चलाएं.- अपने ब्राउज़र में http://localhost:8080/ खोलें.
वेबसाइट की शुरुआती स्थिति की जांच करना
- साइट पर, कोई भी उपयोगकर्ता नाम डालें. इसके बाद, आगे बढ़ें पर क्लिक करें.
- कोई रैंडम पासवर्ड डालें. इसके बाद, साइन इन करें पर क्लिक करें. पासवर्ड को अनदेखा कर दिया जाता है. हालांकि, आपकी पुष्टि अब भी की जाती है और आपको होम पेज पर ले जाया जाता है.
- अगर आपको अपना डिसप्ले नेम बदलना है, तो ऐसा करें. शुरुआती स्थिति में, सिर्फ़ इतना ही किया जा सकता है.
- साइन आउट करें पर क्लिक करें.
इस स्थिति में, उपयोगकर्ताओं को हर बार लॉग इन करते समय पासवर्ड डालना होगा. आपने इस फ़ॉर्म में पासकी की सुविधा जोड़ी है, ताकि उपयोगकर्ता डिवाइस के स्क्रीन लॉक की सुविधा का इस्तेमाल करके साइन इन कर सकें.
पासकी के काम करने के तरीके के बारे में ज़्यादा जानने के लिए, पासकी कैसे काम करती हैं? लेख पढ़ें.
3. पासकी बनाने की सुविधा जोड़ना
उपयोगकर्ताओं को पासकी की मदद से पुष्टि करने की सुविधा देने के लिए, आपको उन्हें पासकी बनाने और रजिस्टर करने की सुविधा देनी होगी. साथ ही, सर्वर पर इसकी सार्वजनिक कुंजी सेव करनी होगी.

आपको उपयोगकर्ता के पासवर्ड से लॉग इन करने के बाद, पासकी बनाने की अनुमति देनी है. साथ ही, एक ऐसा यूज़र इंटरफ़ेस (यूआई) जोड़ना है जिससे उपयोगकर्ता पासकी बना सकें और /home पेज पर रजिस्टर की गई सभी पासकी की सूची देख सकें. अगले सेक्शन में, एक ऐसा फ़ंक्शन बनाया जाता है जो पासकी बनाता है और उसे रजिस्टर करता है.
registerCredential() फ़ंक्शन बनाना
- अपनी पसंद के कोड एडिटर में,
startडायरेक्ट्री खोलें. public/client.jsफ़ाइल पर जाएं. इसके बाद, आखिर तक स्क्रोल करें.- ज़रूरी टिप्पणी के बाद, यह
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 डिक्शनरी के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें ज़रूरी पैरामीटर शामिल हैं:
पैरामीटर | जानकारी |
यह रजिस्ट्रेशन के लिए, | |
उपयोगकर्ता का यूनीक आईडी. यह वैल्यू, एक | |
इस फ़ील्ड में, खाते के लिए एक यूनीक आइडेंटिफ़ायर होना चाहिए. यह ऐसा होना चाहिए जिसे उपयोगकर्ता पहचान सके. जैसे, उसका ईमेल पता या उपयोगकर्ता नाम. यह खाता चुनने वाले टूल में दिखता है. (अगर उपयोगकर्ता नाम का इस्तेमाल किया जाता है, तो पासवर्ड की पुष्टि करने के लिए इस्तेमाल की गई वैल्यू का इस्तेमाल करें.) | |
यह फ़ील्ड, खाते का आसान नाम है. इसे भरना ज़रूरी नहीं है. यह यूनीक होना ज़रूरी नहीं है. यह उपयोगकर्ता का चुना हुआ नाम हो सकता है. अगर आपकी वेबसाइट पर इस एट्रिब्यूट के लिए कोई सही वैल्यू मौजूद नहीं है, तो एक खाली स्ट्रिंग पास करें. यह जानकारी, ब्राउज़र के हिसाब से खाता चुनने वाले टूल पर दिख सकती है. | |
रिलाइंग पार्टी (आरपी) आईडी एक डोमेन होता है. कोई वेबसाइट, अपना डोमेन या रजिस्टर किया जा सकने वाला सफ़िक्स तय कर सकती है. उदाहरण के लिए, अगर किसी आरपी का ऑरिजिन https://login.example.com:1337 है, तो आरपी आईडी | |
इस फ़ील्ड में, आरपी के साथ काम करने वाले सार्वजनिक कुंजी एल्गोरिदम के बारे में बताया जाता है. हमारा सुझाव है कि इसे | |
यह कुकी, पहले से रजिस्टर किए गए क्रेडेंशियल आईडी की सूची उपलब्ध कराती है. इससे एक ही डिवाइस को दो बार रजिस्टर करने से रोका जा सकता है. अगर यह जानकारी दी गई है, तो | |
इसे | |
इसे बूलियन | |
इसे |
क्रेडेंशियल बनाना
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);
- अगली लाइन में,
authenticatorSelection.authenticatorAttachmentको"platform"औरauthenticatorSelection.requireResidentKeyकोtrueपर सेट करें. इससे सिर्फ़ ऐसे प्लैटफ़ॉर्म ऑथेंटिकेटर (डिवाइस) का इस्तेमाल किया जा सकता है जिसमें क्रेडेंशियल का पता लगाने की सुविधा हो.
public/client.js
// Use platform authenticator and discoverable credential.
options.authenticatorSelection = {
authenticatorAttachment: 'platform',
requireResidentKey: true
}
- अगली लाइन में, क्रेडेंशियल बनाने के लिए
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 ऑब्जेक्ट के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें अहम पैरामीटर शामिल हैं:
पैरामीटर | जानकारी |
यह बनाई गई पासकी का Base64URL कोड में बदला गया आईडी होता है. इस आईडी से ब्राउज़र को यह तय करने में मदद मिलती है कि पुष्टि करने के दौरान, डिवाइस में मिलती-जुलती पासकी मौजूद है या नहीं. यह वैल्यू, बैकएंड पर मौजूद डेटाबेस में सेव होनी चाहिए. | |
| |
| |
| |
डिवाइस पर काम करने वाले ट्रांसपोर्ट की सूची: | |
पासकी की सुविधा वाले डिवाइस पर यह क्रेडेंशियल बनाए जाने पर, |
क्रेडेंशियल ऑब्जेक्ट को सर्वर पर भेजने के लिए, यह तरीका अपनाएं:
- क्रेडेंशियल के बाइनरी पैरामीटर को 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);
- अगली लाइन में, ऑब्जेक्ट को सर्वर पर भेजें:
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() फ़ंक्शन उपलब्ध होने के बाद, आपको इसे चालू करने के लिए एक बटन की ज़रूरत होगी. साथ ही, आपको रजिस्टर की गई पासकी की सूची दिखानी होगी.

प्लेसहोल्डर एचटीएमएल जोड़ना
- एडिटर में,
views/home.htmlफ़ाइल पर जाएं. - ज़रूरी टिप्पणी के बाद, यूज़र इंटरफ़ेस (यूआई) का ऐसा प्लेसहोल्डर जोड़ें जो पासकी रजिस्टर करने के लिए बटन और पासकी की सूची दिखाता हो:
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 क्लास को हटाना होगा.
यह देखने के लिए कि किसी एनवायरमेंट में पासकी इस्तेमाल की जा सकती हैं या नहीं, यह तरीका अपनाएं:
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) {
- शर्त के मुख्य हिस्से में, यह देखें कि डिवाइस पर पासकी बनाई जा सकती है या नहीं. इसके बाद, यह देखें कि फ़ॉर्म में अपने-आप भरने की सुविधा के लिए, पासकी का सुझाव दिया जा सकता है या नहीं.
views/home.html
try {
const capabilities = await PublicKeyCredential.getClientCapabilities();
// Is conditional UI available in this browser?
if (capabilities.conditionalGet === true &&
capabilities.passkeyPlatformAuthenticator === true) {
- अगर सभी शर्तें पूरी होती हैं, तो पासकी बनाने का बटन दिखाएं. ऐसा न होने पर, चेतावनी वाला मैसेज दिखाएं.
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.';
}
रजिस्टर की गई पासकी को सूची में रेंडर करना
- एक
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);
};
- अगली लाइन में,
renderCredentials()फ़ंक्शन को शुरू करें, ताकि उपयोगकर्ता के/homeपेज पर पहुंचते ही, रजिस्टर की गई पासकी दिखें.
views/home.html
renderCredentials();
पासकी बनाना और रजिस्टर करना
पासकी बनाने और रजिस्टर करने के लिए, आपको registerCredential() फ़ंक्शन को कॉल करना होगा. इसे आपने पहले लागू किया था.
पासकी बनाएं बटन पर क्लिक करने पर, registerCredential() फ़ंक्शन को ट्रिगर करने के लिए, यह तरीका अपनाएं:
- प्लेसहोल्डर एचटीएमएल के बाद, फ़ाइल में यह
importस्टेटमेंट ढूंढें:
views/home.html
import {
$,
_fetch,
loading,
updateCredential,
unregisterCredential,
} from '/client.js';
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';
- फ़ाइल के आखिर में, काम की टिप्पणी के बाद एक
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();
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);
}
}
};
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);
इसे आज़माएं
अगर आपने अब तक दिए गए सभी चरणों को पूरा कर लिया है, तो आपने वेबसाइट पर पासकी बनाने, रजिस्टर करने, और दिखाने की सुविधा लागू कर ली है!
इसे आज़माने के लिए, यह तरीका अपनाएं:
- साइट पर, किसी भी उपयोगकर्ता नाम और पासवर्ड से साइन इन करें.
- पासकी बनाएं पर क्लिक करें.
- डिवाइस के स्क्रीन लॉक का इस्तेमाल करके, अपनी पहचान की पुष्टि करें.
- पुष्टि करें कि वेब पेज के आपकी रजिस्टर की गई पासकी सेक्शन में, पासकी रजिस्टर की गई हो और दिख रही हो.

रजिस्टर की गई पासकी का नाम बदलना और उन्हें हटाना
आपके पास सूची में मौजूद, रजिस्टर की गई पासकी का नाम बदलने या उन्हें मिटाने का विकल्प होना चाहिए. कोडलैब के साथ आने वाले कोड में, यह देखा जा सकता है कि यह कैसे काम करता है.
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 डिक्शनरी के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें ज़रूरी पैरामीटर शामिल हैं:
पैरामीटर | जानकारी |
| |
आरपी आईडी एक डोमेन होता है. कोई वेबसाइट, अपना डोमेन या रजिस्टर किया जा सकने वाला सफ़िक्स तय कर सकती है. यह वैल्यू, पासकी बनाते समय इस्तेमाल किए गए | |
इस प्रॉपर्टी का इस्तेमाल, पुष्टि करने के लिए ज़रूरी शर्तें पूरी करने वाले पुष्टि करने वाले लोगों को ढूंढने के लिए किया जाता है. ब्राउज़र को खाता चुनने वाला टूल दिखाने की अनुमति देने के लिए, एक खाली कलेक्शन पास करें या इसे तय न करें. इस बारे में ज़्यादा जानें कि | |
इसे |
उपयोगकर्ता की स्थानीय तौर पर पुष्टि करना और क्रेडेंशियल पाना
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);
- जब कोई उपयोगकर्ता पुष्टि करता है, तब खाता चुनने वाला टूल खोलने के लिए,
allowCredentialsपैरामीटर में एक खाली कलेक्शन पास करें:
public/client.js
// An empty allowCredentials array invokes an account selector by discoverable credentials.
options.allowCredentials = [];
खाता चुनने वाला टूल, उपयोगकर्ता की उस जानकारी का इस्तेमाल करता है जो पासकी के साथ सेव की गई है.
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 ऑब्जेक्ट के सभी पैरामीटर शामिल नहीं हैं. हालांकि, इसमें अहम पैरामीटर शामिल हैं:
पैरामीटर | जानकारी |
पुष्टि किए गए पासकी क्रेडेंशियल का Base64URL कोड में बदला गया आईडी. | |
| |
क्लाइंट के डेटा का | |
पुष्टि करने वाले व्यक्ति के डेटा का | |
हस्ताक्षर का | |
यह एक | |
जब यह क्रेडेंशियल लोकल डिवाइस से आता है, तो यह फ़ंक्शन |
क्रेडेंशियल ऑब्जेक्ट को सर्वर पर भेजने के लिए, यह तरीका अपनाएं:
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);
- ऑब्जेक्ट को सर्वर पर भेजें:
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 की एक सुविधा है. इसमें फ़ॉर्म के इनपुट फ़ील्ड को इस तरह से बनाया जा सकता है कि वह पासवर्ड के साथ-साथ, पासकी को भी अपने-आप भरने वाले आइटम के तौर पर सुझाए. अगर कोई व्यक्ति, अपने-आप भरने की सुविधा के सुझावों में मौजूद किसी पासकी पर टैप करता है, तो उसे डिवाइस के स्क्रीन लॉक का इस्तेमाल करके, स्थानीय तौर पर अपनी पहचान की पुष्टि करने के लिए कहा जाता है. इससे उपयोगकर्ताओं को बेहतर अनुभव मिलता है, क्योंकि उपयोगकर्ता की कार्रवाई, पासवर्ड के ज़रिए साइन-इन करने की कार्रवाई से मिलती-जुलती होती है.

शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) चालू करना
शर्त के हिसाब से यूज़र इंटरफ़ेस (यूआई) को चालू करने के लिए, आपको सिर्फ़ इनपुट फ़ील्ड के 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 को चालू करना, और शर्तों के हिसाब से यूज़र इंटरफ़ेस (यूआई) को चालू करना
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() फ़ंक्शन को इंपोर्ट करता है. इस फ़ंक्शन को आपने पहले लागू किया था.
- पुष्टि करें कि
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);
}
}
}
इसे आज़माएं
आपने अपनी वेबसाइट पर पासकी बनाने, रजिस्टर करने, दिखाने, और पुष्टि करने की सुविधा लागू की हो.
इसे आज़माने के लिए, यह तरीका अपनाएं:
- 'झलक' टैब पर जाएं.
- अगर ज़रूरी हो, तो साइन आउट करें.
- उपयोगकर्ता नाम वाले टेक्स्ट बॉक्स पर क्लिक करें. आपको एक डायलॉग दिखेगा.
- वह खाता चुनें जिससे आपको साइन इन करना है.
- डिवाइस के स्क्रीन लॉक का इस्तेमाल करके, अपनी पहचान की पुष्टि करें. आपको
/homeपेज पर रीडायरेक्ट कर दिया जाएगा और आपने साइन इन कर लिया होगा.

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