सुरक्षा कुंजी (WebAuthn) की मदद से, दो तरीकों से पुष्टि करने की सुविधा का इस्तेमाल करके, अपनी साइट को सुरक्षित करें

1. आप क्या बनाएंगे #39;

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

इसके बाद, आप WebAuthn के आधार पर दो तरीकों से पुष्टि करने के लिए, सुरक्षा कुंजी की मदद से सहायता जोड़ पाएंगे. ऐसा करने के लिए, आप ये लागू करेंगे:

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

16ce77744061c5f7.png

तैयार वेब ऐप्लिकेशन पर एक नज़र डालें और उसे आज़माएं.

2. WebAuthn के बारे में जानकारी

WebAuthn से जुड़ी बुनियादी बातें

WebAuthn क्यों?

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

वेब ऑथेंटिकेशन एपीआई या WebAuthn, स्टैंडर्ड मानकों वाला फ़िशिंग से बचाव करने वाला प्रोटोकॉल है. इसका इस्तेमाल कोई भी वेब ऐप्लिकेशन कर सकता है.

यह टूल कैसे काम करता है

स्रोत: webauthn.guide

WebAuthn सर्वर को पासवर्ड के बजाय सार्वजनिक कुंजी क्रिप्टोग्राफ़ी का इस्तेमाल करके रजिस्टर और प्रमाणीकृत करने की सुविधा देता है. वेबसाइटें, क्रेडेंशियल बना सकती हैं. इसमें निजी-सार्वजनिक कुंजी शामिल होती है.

  • निजी कुंजी को उपयोगकर्ता के डिवाइस पर सुरक्षित तरीके से सेव किया जाता है.
  • स्टोरेज के लिए सार्वजनिक कुंजी और रैंडम क्रेडेंशियल आईडी को सर्वर पर भेजा जाता है.

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

फ़ायदे

WebAuthn के दो मुख्य फ़ायदे हैं:

  • कोई शेयर किया गया सीक्रेट नहीं: सर्वर किसी भी सीक्रेट को स्टोर नहीं करता. इससे डेटाबेस, हैकर के लिए कम दिलचस्प हो जाता है, क्योंकि सार्वजनिक कुंजियां उनके लिए काम की नहीं होती हैं.
  • दायरे के क्रेडेंशियल: site.example के लिए रजिस्टर किए गए क्रेडेंशियल को evil-site.example पर इस्तेमाल नहीं किया जा सकता. इससे WebAuthn फ़िशिंग-प्रूफ़ हो जाता है.

इस्तेमाल के उदाहरण

WebAuthn के लिए इस्तेमाल का एक तरीका सुरक्षा कुंजी के साथ दो तरीकों से पुष्टि करना है. यह खास तौर पर एंटरप्राइज़ वेब ऐप्लिकेशन के लिए काम का हो सकता है.

ब्राउज़र समर्थन

इसे Google, Mozilla, Microsoft, Yubico, और दूसरी कंपनियों की गतिविधियों के साथ W3C और FIDO ने लिखा है.

शब्दावली

  • Authenticator: कोई सॉफ़्टवेयर या हार्डवेयर इकाई जो उपयोगकर्ता को रजिस्टर कर सकती है और बाद में रजिस्टर किए गए क्रेडेंशियल के मालिक होने का दावा कर सकती है. पुष्टि करने वाले दो तरह के होते हैं:
  • रोमिंग की पुष्टि करने वाला प्रोग्राम: पुष्टि करने वाला प्रोग्राम, जिसे ऐसे किसी भी डिवाइस के साथ इस्तेमाल किया जा सकता है जिससे उपयोगकर्ता साइन इन करने की कोशिश कर रहा है. उदाहरण: यूएसबी सुरक्षा कुंजी, स्मार्टफ़ोन.
  • प्लैटफ़ॉर्म की पुष्टि करना: यह उपयोगकर्ता के डिवाइस में पहले से मौजूद होता है. उदाहरण: Apple's Touch ID.
  • क्रेडेंशियल: निजी सार्वजनिक कुंजी के जोड़े
  • भरोसेमंद पक्ष: उपयोगकर्ता की पुष्टि करने की कोशिश करने वाली वेबसाइट के लिए सर्वर
  • FIDO सर्वर: पुष्टि करने के लिए इस्तेमाल किया जाने वाला सर्वर. FIDO, FIDO गठबंधन के बनाए गए प्रोटोकॉल का एक परिवार है. इनमें से एक प्रोटोकॉल WebAuthn है.

इस वर्कशॉप में, हम रोमिंग # पुष्टि करने वाले का इस्तेमाल करेंगे.

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

आपको इनकी ज़रूरत होगी

इस कोडलैब को पूरा करने के लिए, आपको इनकी ज़रूरत होगी:{0}

  • WebAuthn के बारे में बुनियादी जानकारी.
  • JavaScript और एचटीएमएल की बुनियादी जानकारी.
  • अप-टू-डेट ब्राउज़र जो WebAuthn के साथ काम करता है.
  • ऐसी सुरक्षा कुंजी जो U2F के नियमों का पालन करती हो.

इनमें से किसी एक का इस्तेमाल, सुरक्षा कुंजी के तौर पर किया जा सकता है:

  • Android>=7 (Nougat) वाला Android फ़ोन जो Chrome पर काम करता है. इस मामले में, आपको Windows, macOS या Chrome OS मशीन की ज़रूरत होगी, जिस पर ब्लूटूथ काम कर रहा हो.
  • यूएसबी कुंजी, जैसे कि YubiKey.

6539dc7ffec2538c.png

स्रोत: https://www.Yubico.com/products/security-key/

dd56e2cfe0f7ced2.png

आप इन चीज़ों के बारे में जानेंगे

आप जानेंगे ✨

  • WebAuthn पुष्टि करने के लिए, सुरक्षा कुंजी को रजिस्टर करने और उसका इस्तेमाल दूसरे तरीके के रूप में करने का तरीका.
  • इस प्रक्रिया को उपयोगकर्ता के लिए आसान बनाने का तरीका.

आप सीखेंगे #39;जानें ❌

  • FIDO सर्वर कैसे बनाएं—पुष्टि करने के लिए इस्तेमाल किया जाने वाला सर्वर. यह ठीक है, क्योंकि आम तौर पर वेब ऐप्लिकेशन या साइट डेवलपर के तौर पर, आपको मौजूदा FIDO सर्वर लागू करने की ज़रूरत होगी. पक्का करें कि आप जिस सर्वर पर भरोसा करते हैं उसके काम करने के तरीके और उसकी क्वालिटी की हमेशा पुष्टि करें. इस कोडलैब में, FIDO सर्वर SimpleWebAuthn का इस्तेमाल करता है. दूसरे विकल्पों के लिए, FIDO Alliance का आधिकारिक पेज देखें. ओपन सोर्स लाइब्रेरी के लिए, webauthn.io या AwesomeWebAuthn देखें.

खंडन

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

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

4. पुष्टि करने वाला ऐप्लिकेशन सेट अप करें

अगर आप पुष्टि करने के तौर पर Android फ़ोन का इस्तेमाल कर रहे हैं

  • पक्का करें कि Chrome आपके डेस्कटॉप और आपके फ़ोन, दोनों पर अप-टू-डेट हो.
  • अपने डेस्कटॉप और फ़ोन, दोनों पर Chrome खोलें और उसी प्रोफ़ाइल से साइन इन करें⏤जिस प्रोफ़ाइल का इस्तेमाल आप इस वर्कशॉप के लिए करना चाहते हैं.
  • अपने डेस्कटॉप और फ़ोन पर, इस प्रोफ़ाइल के लिए सिंक की सुविधा चालू करें. इसके लिए chrome://settings/syncSetup का इस्तेमाल करें.
  • अपने डेस्कटॉप और फ़ोन, दोनों पर ब्लूटूथ चालू करें.
  • Chrome डेस्कटॉप पर उसी प्रोफ़ाइल से लॉग इन किया गया है और webauthn.io खोलें.
  • कोई आसान उपयोगकर्ता नाम डालें. प्रमाणित करने का टाइप और पुष्टि करने वाला टाइप को कोई नहीं और बताया नहीं गया (डिफ़ॉल्ट) वैल्यू पर छोड़ दें. रजिस्टर करें पर क्लिक करें.

6b49f0298f5a0af.png

  • ब्राउज़र की विंडो खुल जाएगी, जिसमें आपसे अपनी पहचान की पुष्टि करने के लिए कहा जाएगा. सूची में से अपना फ़ोन चुनें.

आमने-सामने 852de328fcd4eb42.png

  • अपने फ़ोन पर, आपको अपनी पहचान की पुष्टि करें शीर्षक वाली सूचना मिलेगी. फिर उस पर टैप करें.
  • फ़ोन पर, आपका फ़ोन पिन कोड (या फ़िंगरप्रिंट सेंसर को छूने के लिए) मांगा जाएगा. इसे डालें.
  • आपके डेस्कटॉप पर webauthn.io पर, एक "सफल&कोटेशन; सूचक दिखना चाहिए.

fc0acf00a4d412fa.png

  • अपने डेस्कटॉप पर webauthn.io पर, 'लॉगिन करें' बटन पर क्लिक करें.
  • फिर से, ब्राउज़र विंडो खुलनी चाहिए; सूची में अपना फ़ोन चुनें.
  • अपने फ़ोन पर, पॉप-अप होने की सूचना पर टैप करें और अपना पिन डालें (या फ़िंगरप्रिंट सेंसर को छुएं).
  • webauthn.io से आपको यह बताना होगा कि आप #39;लॉग इन हैं. आपका फ़ोन सुरक्षा कुंजी के रूप में ठीक से काम कर रहा है; आप वर्कशॉप के लिए पूरी तरह से तैयार हैं!

अगर आप पुष्टि करने के तौर पर यूएसबी सुरक्षा कुंजी का इस्तेमाल कर रहे हैं{0/}

  • Chrome डेस्कटॉप में, webauthn.io खोलें.
  • कोई आसान उपयोगकर्ता नाम डालें. प्रमाणित करने का टाइप और पुष्टि करने वाला टाइप को कोई नहीं और बताया नहीं गया (डिफ़ॉल्ट) वैल्यू पर छोड़ दें. रजिस्टर करें पर क्लिक करें.
  • ब्राउज़र की विंडो खुल जाएगी, जिसमें आपसे अपनी पहचान की पुष्टि करने के लिए कहा जाएगा. सूची में USB सुरक्षा कुंजी चुनें.

आमने-सामने 9575f04e43da035.png

  • अपनी सुरक्षा कुंजी को डेस्कटॉप पर डालें और उसे छुएं.

923d5adb8aa8286c.png

  • आपके डेस्कटॉप पर webauthn.io पर, एक "सफल&कोटेशन; सूचक दिखना चाहिए.

fc0acf00a4d412fa.png

  • अपने डेस्कटॉप पर webauthn.io पर, लॉगिन करें बटन पर क्लिक करें.
  • इसके बाद, ब्राउज़र विंडो खुलनी चाहिए; सूची में यूएसबी सुरक्षा कुंजी चुनें.
  • कुंजी को छुएं.
  • Webauthn.io से आपको यह बताना होगा कि आप #39;लॉग इन हैं. आपकी USB सुरक्षा कुंजी ठीक से काम कर रही है; आप वर्कशॉप के लिए पूरी तरह से तैयार हैं!

7e1c0bb19c9f3043.png

5. सेट अप करें

इस कोडलैब में आप #ग्लिच का इस्तेमाल करेंगे. यह एक ऑनलाइन कोड एडिटर है, जो आपके कोड को अपने-आप और तुरंत डिप्लॉय करता है.

स्टार्टर कोड फ़ोर्क करें

स्टार्टर प्रोजेक्ट खोलें.

Remix बटन पर क्लिक करें.

इससे स्टार्टर कोड की एक कॉपी बन जाती है. अब आपके पास बदलाव करने के लिए अपना कोड है. आपका फ़ोर्क (इसे "remix&कोटेशन; ग्लिच में) कहते हैं, आप इस #लैब के लिए सारे काम करेंगे.

cf2b9f552c9809b6.png

स्टार्टर कोड एक्सप्लोर करें

आपने जो स्टार्टर कोड #39; चुना है, उसे थोड़ी देर के लिए एक्सप्लोर कर लें.

ध्यान रखें कि libs के तहत, auth.js नाम की लाइब्रेरी पहले से ही मौजूद है. यह एक कस्टम लाइब्रेरी है, जो सर्वर साइड ऑथेंटिकेशन लॉजिक का ध्यान रखती है. यह fido लाइब्रेरी को डिपेंडेंसी के तौर पर इस्तेमाल करता है.

6. क्रेडेंशियल रजिस्ट्रेशन लागू करना

क्रेडेंशियल रजिस्ट्रेशन लागू करना

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

आइए, सबसे पहले एक ऐसा फ़ंक्शन जोड़ें जो हमारे क्लाइंट-साइड कोड में ऐसा करता हो.

public/auth.client.js में, ध्यान दें कि registerCredential() इसमें नीचे दिया गया कोड जोड़ें:

async function registerCredential() {
  // Fetch the credential creation options from the backend
  const credentialCreationOptionsFromServer = await _fetch(
    "/auth/credential-options",
    "POST"
  );
  // Decode the credential creation options
  const credentialCreationOptions = decodeServerOptions(
    credentialCreationOptionsFromServer
  );
  // Create a credential via the browser API; this will prompt the user to touch their security key or tap a button on their phone
  const credential = await navigator.credentials.create({
    publicKey: {
      ...credentialCreationOptions,
    }
  });
  // Encode the newly created credential to send it to the backend
  const encodedCredential = encodeCredential(credential);
  // Send the encoded credential to the backend for storage
  return await _fetch("/auth/credential", "POST", encodedCredential);
}

ध्यान दें कि यह फ़ंक्शन आपके लिए पहले से ही एक्सपोर्ट किया गया है.

यहां बताया गया है कि registerCredential क्या करता है:

  • यह सर्वर (/auth/credential-options) से क्रेडेंशियल बनाने के विकल्प फ़ेच करता है
  • सर्वर विकल्प वापस एन्कोड किए जाते हैं, इसलिए वे इसे डिकोड करने के लिए उपयोगिता फ़ंक्शन decodeServerOptions का इस्तेमाल करते हैं.
  • यह वेब एपीआई navigator.credential.create को कॉल करके क्रेडेंशियल बनाता है. जब navigator.credential.create को कॉल किया जाता है, तो ब्राउज़र उस फ़ाइल को कंट्रोल कर लेता है और उपयोगकर्ता से सुरक्षा कुंजी चुनने के लिए कहता है.
  • यह नए बनाए गए क्रेडेंशियल को डीकोड करता है
  • यह /auth/credential के लिए अनुरोध करके, नए क्रेडेंशियल सर्वर-साइड को रजिस्टर करता है. इस अनुरोध में, कोड में बदला गया क्रेडेंशियल शामिल होता है.

एक ओर: सर्वर कोड देखें

registerCredential() सर्वर को दो कॉल करता है, इसलिए चलिए कुछ देखते हैं कि बैकएंड में क्या हो रहा है.

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

जब क्लाइंट /auth/credential-options के लिए अनुरोध करता है, तो सर्वर एक विकल्प ऑब्जेक्ट जनरेट करता है और उसे वापस क्लाइंट को भेज देता है.

इसके बाद, क्लाइंट इस क्रेडेंशियल का इस्तेमाल, क्रेडेंशियल बनाने के लिए किए गए असल कॉल में करता है:

navigator.credentials.create({
    publicKey: {
    // Options generated server-side
    ...credentialCreationOptions
// ...
}

इसलिए, आपने क्लाइंट-साइड registerCredential में credentialCreationOptions और #39; का इस्तेमाल पिछले चरण में क्या किया?

router.post&&kot;/क्रेडेंशियल-विकल्प &कोटेशन;, ... में सर्वर कोड देखें.

हर एक प्रॉपर्टी पर नज़र नहीं डालता, लेकिन यहां कुछ दिलचस्प चीज़ें दी गई हैं, जिन्हें आप सर्वर कोड में और #39; के विकल्प ऑब्जेक्ट में देख सकते हैं. ये ऑब्जेक्ट, fido2 लाइब्रेरी का इस्तेमाल करके जनरेट किए जाते हैं और क्लाइंट को लौटा दिए जाते हैं:

  • rpName और rpId उस संगठन के बारे में बताते हैं जो उपयोगकर्ता को रजिस्टर करता है और उसकी पुष्टि करता है. याद रखें कि WebAuthn में, क्रेडेंशियल किसी खास डोमेन के दायरे में आते हैं, जो सुरक्षा से जुड़ा फ़ायदा होता है; क्रेडेंशियल का दायरा तय करने के लिए rpName और rpId का इस्तेमाल किया जाता है. एक मान्य rpId, आपकी साइट का होस्टनाम है. ध्यान दें कि जब आप स्टार्टर प्रोजेक्ट 🧘🏻 ♀️ चालू करते हैं, तो ये अपने-आप कैसे अपडेट हो जाएंगे
  • excludeCredentials, क्रेडेंशियल की एक सूची है; नया क्रेडेंशियल किसी पुष्टि करने वाले के लिए नहीं बनाया जा सकता, जिसमें excludeCredentials में मौजूद क्रेडेंशियल भी शामिल हो. हमारे कोडलैब (कोड बनाना सीखना) में, excludeCredentials इस उपयोगकर्ता के लिए मौजूदा क्रेडेंशियल की सूची है. इसे और user.id से हम यह पक्का करते हैं कि उपयोगकर्ता के बनाए गए हर क्रेडेंशियल एक अलग पुष्टि करने वाले (सुरक्षा कुंजी) पर लाइव रहेंगे. यह एक अच्छा तरीका है. इसका मतलब है कि अगर किसी उपयोगकर्ता ने एक से ज़्यादा क्रेडेंशियल रजिस्टर किए हैं, तो वे अलग-अलग पुष्टि करने वालों (सुरक्षा कुंजियां) का इस्तेमाल करेंगे. इसलिए, एक सुरक्षा कुंजी को खो देने पर उपयोगकर्ता, अपने खाते को लॉक नहीं कर पाएगा.
  • authenticatorSelection से पुष्टि की जाती है कि आप अपने वेब ऐप्लिकेशन में किस तरह के पुष्टि करने वालों को अनुमति देना चाहते हैं. आइए authenticatorSelection पर नज़र डालें:
    • residentKey: preferred का मतलब है कि यह ऐप्लिकेशन क्लाइंट-साइड पर खोजे जाने लायक क्रेडेंशियल लागू नहीं करता है. क्लाइंट-साइड खोजा जा सकने वाला क्रेडेंशियल, एक खास तरह का क्रेडेंशियल है. इसकी मदद से, उपयोगकर्ता की पहचान किए बिना ही उसकी पुष्टि की जा सकती है. यहां हमने #39;preferred को सेट अप किया है, क्योंकि यह कोडलैब बुनियादी तौर पर लागू करने पर फ़ोकस करता है. ज़्यादा बेहतर फ़्लो के लिए, खोजे जा सकने वाले क्रेडेंशियल हैं.
    • requireResidentKey सिर्फ़ WebAuthn v1 के साथ पीछे जाने की सुविधा के लिए उपलब्ध है.
    • userVerification: preferred का मतलब है कि अगर पुष्टि करने वाला व्यक्ति, उपयोगकर्ता की पुष्टि करने की सुविधा का इस्तेमाल करता है—उदाहरण के लिए, अगर यह बायोमेट्रिक सुरक्षा कुंजी या पहले से मौजूद पिन सुविधा वाली कुंजी है, तो क्रेडेंशियल बनाने के दौरान भरोसेमंद पक्ष इसका अनुरोध करेगा. अगर पुष्टि करने वाला, मूल सुरक्षा कुंजी—'t नहीं है, तो सर्वर पुष्टि करने का अनुरोध नहीं करेगा.
  • ​​pubKeyCredParam, अपनी पसंद के हिसाब से क्रेडेंशियल की पसंद के मुताबिक क्रिप्टोग्राफ़िक प्रॉपर्टी दिखाता है.

ये सभी विकल्प, वेब ऐप्लिकेशन के सुरक्षा मॉडल के बारे में हैं. ध्यान रखें कि सर्वर पर, ये विकल्प एक ही authSettings ऑब्जेक्ट में तय किए गए हैं.

चुनौती

एक और दिलचस्प बात req.session.challenge = options.challenge; है.

WebAuthn एक क्रिप्टोग्राफ़िक प्रोटोकॉल है, इसलिए यह रीप्ले हमलों से बचने के लिए किसी भी क्रम में चुनौती पर निर्भर करता है—जब कोई हमलावर पुष्टि करने के लिए पेलोड चुराता है, जब वह पुष्टि करने की सुविधा वाली निजी कुंजी का मालिक नहीं होता है.

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

क्रेडेंशियल रजिस्ट्रेशन कोड

router.post&"/credential&quat;, ...में सर्वर कोड देखें.

यहां क्रेडेंशियल, रजिस्टर किए गए सर्वर-साइड पर मिलते हैं.

तो इस जगह पर क्या हो रहा है?

पुष्टि करने का यह कॉल, इस कोड में सबसे ज़रूरी बिट में से एक है: fido2.verifyAttestationResponse से:

  • साइन की गई चुनौती की जांच की जाती है. इससे यह पक्का होता है कि क्रेडेंशियल किसी ऐसे व्यक्ति ने बनाया है जिसने खाता बनाते समय निजी कुंजी को रोक दिया है.
  • विश्वसनीय पक्ष के मूल आईडी तक सीमित आईडी की भी पुष्टि होती है. इससे क्रेडेंशियल इस वेब ऐप्लिकेशन (और सिर्फ़ इस वेब ऐप्लिकेशन) से जुड़ा होगा.

इस फ़ंक्शन को यूज़र इंटरफ़ेस (यूआई) में जोड़ें

अब क्रेडेंशियल बनाने के लिए आपका फ़ंक्शन, ``रजिस्टर क्रेडेंशियल(), तैयार है, चलिए इसे #39; उपयोगकर्ता के लिए उपलब्ध कराते हैं.

आप इसे खाता पेज से कर रहे हैं, क्योंकि यह पुष्टि करने के प्रबंधन के लिए आम जगह है.

account.html's मार्कअप में, उपयोगकर्ता नाम के नीचे, #39; बहुत खाली div लेआउट क्लास के साथ class="flex-h-between" है. हमdiv का इस्तेमाल, यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए करेंगे, जो 2FA फ़ंक्शन से जुड़ा है.

इस div को जोड़ें:

  • ऐसा शीर्षक जिसमें & &vt दो दो तरीकों से पुष्टि करने की सुविधा की सुविधा हो;
  • क्रेडेंशियल बनाने के लिए एक बटन
 <div class="flex-h-between">
    <h3>
        Two-factor authentication
    </h3>
    <button class="create" id="registerButton" raised>
        ➕ Add a credential
    </button>
</div>

इस डाइव के नीचे, वह क्रेडेंशियल शेयर करें जिसकी हमें बाद में ज़रूरत होगी:

<div class="flex-h-between">
(HTML you've just added)
</div>
<div id="credentials"></div>

account.html इनलाइन स्क्रिप्ट में, अभी और बनाए गए फ़ंक्शन को इंपोर्ट करें. register फ़ंक्शन जोड़ने वाले फ़ंक्शन के साथ-साथ, अभी-अभी बनाए गए बटन से जुड़ा इवेंट हैंडलर #&39 जोड़ें.

// Set up the handler for the button that registers credentials
const registerButton = document.querySelector('#registerButton');
registerButton.addEventListener('click', register);

// Register a credential
async function register() {
  let user = {};
  try {
    const user = await registerCredential();
  } catch (e) {
    // Alert the user that something went wrong
    if (Array.isArray(e)) {
      alert(
        // `msg` not `message`, this is the key's name as per the express validator API
        `Registration failed. ${e.map((err) => `${err.msg} (${err.param})`)}`
      );
    } else {
      alert(`Registration failed. ${e}`);
    }
  }
}

उपयोगकर्ता के देखने के लिए क्रेडेंशियल दिखाएं

अब आपने ##39; क्रेडेंशियल बनाने की सुविधा जोड़ दी है, इसलिए उपयोगकर्ताओं को अपने जोड़े गए क्रेडेंशियल देखने की ज़रूरत होती है.

खाता पेज, इसके लिए एक अच्छा स्थान है.

account.html में, updateCredentialList() नाम के फ़ंक्शन को ढूंढें.

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

// Update the list that displays credentials
async function updateCredentialList() {
  // Fetch the latest credential list from the backend
  const response = await _fetch('/auth/credentials', 'GET');
  const credentials = response.credentials || [];
  // Generate the credential list as HTML and pass remove/rename functions as args
  const credentialListHtml = getCredentialListHtml(
    credentials,
    removeEl,
    renameEl
  );
  // Display the list of credentials in the DOM
  const list = document.querySelector('#credentials');
  render(credentialListHtml, list);
}    

अभी के लिए, removeEl और renameEl को ध्यान में न रखें; इस कोडलैब में आप बाद में इनके बारे में जानेंगे.

अपनी इनलाइन स्क्रिप्ट की शुरुआत में, account.html के अंदर updateCredentialList में एक कॉल जोड़ें. इस कॉल से, जब उपयोगकर्ता अपने खाता पेज पर आता है, तब उपलब्ध क्रेडेंशियल फ़ेच किए जाते हैं.

<script type="module">
    // ... (imports)
    // Initialize the credential list by updating it once on page load
    updateCredentialList();

अब, registerCredential के पूरा होने के बाद updateCredentialList को कॉल करें, ताकि सूचियां नए क्रेडेंशियल को दिखा सकें:

async function register() {
  let user = {};
  try {
    // ...
  } catch (e) {
    // ...
  }
  // Refresh the credential list to display the new credential
  await updateCredentialList();
}

इसे आज़माएं! CANNOT TRANSLATE

आप #39; क्रेडेंशियल रजिस्ट्रेशन के साथ काम पूरा कर चुके हैं! उपयोगकर्ता, अब सुरक्षा कुंजी पर आधारित क्रेडेंशियल बना सकते हैं और उन्हें अपने खाता पेज पर देख सकते हैं.

इसे आजमाएं:

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

7. दो तरीकों से पुष्टि करने की सुविधा चालू करें

आपके उपयोगकर्ता क्रेडेंशियल रजिस्टर और रजिस्टर कर सकते हैं, लेकिन क्रेडेंशियल सिर्फ़ दिखाए जाते हैं और अभी तक उनका इस्तेमाल नहीं किया गया है.

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

इस अनुभाग में, आप इस बुनियादी फ़्लो से अपने वेब ऐप्लिकेशन में प्रमाणीकरण प्रवाह बदल देंगे:

6f49a7e520836d0.png

दो तरीकों से फ़्लो करने के लिए:

e7409946cd88efc7.png

दो तरीकों से पुष्टि करने की सुविधा लागू करें

आइए, सबसे पहले अपनी उस फ़ंक्शन को जोड़ें जिसकी हमें ज़रूरत है. साथ ही, हम बैकएंड के साथ कम्यूनिकेशन को लागू करते हैं. हम इसे अगले चरण में फ़्रंटएंड में जोड़ेंगे.

आपको यहां जिस फ़ंक्शन को लागू करना है वह उपयोगकर्ता को क्रेडेंशियल से पुष्टि करने वाला फ़ंक्शन है.

public/auth.client.js में, खाली फ़ंक्शन authenticateTwoFactor को खोजें और उसे नीचे दिए गए कोड में जोड़ें:

async function authenticateTwoFactor() {
  // Fetch the 2F options from the backend
  const optionsFromServer = await _fetch("/auth/two-factor-options", "POST");
  // Decode them
  const decodedOptions = decodeServerOptions(optionsFromServer);
  // Get a credential via the browser API; this will prompt the user to touch their security key or tap a button on their phone
  const credential = await navigator.credentials.get({
    publicKey: decodedOptions
  });
  // Encode the credential
  const encodedCredential = encodeCredential(credential);
  // Send it to the backend for verification
  return await _fetch("/auth/authenticate-two-factor", "POST", {
    credential: encodedCredential
  });
}

ध्यान दें कि यह फ़ंक्शन आपके लिए पहले से ही एक्सपोर्ट किया जा चुका है; हमें अगले चरण में इसकी ज़रूरत पड़ेगी.

यहां बताया गया है कि authenticateTwoFactor क्या करता है:

  • यह सर्वर से, दो तरीकों से पुष्टि करने के विकल्प का अनुरोध करता है. ठीक आपके बनाए गए क्रेडेंशियल बनाने के विकल्पों की तरह ही, आपकी वेबसाइट को पहले देखे गए #39; वेब सर्वर के लिए, इन सुरक्षा विकल्पों पर निर्भर करता है. ज़्यादा जानकारी के लिए, router.post("/two-factors-options", ... के तहत सर्वर कोड में जाएं.
  • navigator.credentials.get को कॉल करने पर, यह ब्राउज़र को रजिस्टर कर लेता है. साथ ही, उपयोगकर्ता को पहले से रजिस्टर की गई कुंजी डालने और उसे छूने की सूचना देता है. इससे, पुष्टि करने के दूसरे तरीके का इस्तेमाल करने के लिए, क्रेडेंशियल चुने जाते हैं.
  • इसके बाद, चुने गए क्रेडेंशियल को बैकएंड अनुरोध में पास किया जाता है, ताकि फ़ेच किया जा सके(&quat;/auth/authenticate-two-फ़ैक्ट&kot;`. अगर क्रेडेंशियल उस उपयोगकर्ता के लिए मान्य है, तो उपयोगकर्ता की पुष्टि हो जाती है.

एक ओर: सर्वर कोड देखें

ध्यान दें कि server.js पहले से ही कुछ नेविगेशन और ऐक्सेस का ध्यान रखता है: यह पक्का करता है कि खाता पेज को सिर्फ़ पुष्टि किए गए उपयोगकर्ता ही ऐक्सेस कर सकते हैं और कुछ ज़रूरी रीडायरेक्ट करता है.

अब, router.post("/initialize-authentication", ... के तहत सर्वर कोड पर एक नज़र डालें.

यहां दो दिलचस्प बातें बताई गई हैं:

  • इस चरण में, पासवर्ड और क्रेडेंशियल, दोनों की एक साथ जांच की जाती है. यह एक सुरक्षा उपाय है: जिन उपयोगकर्ताओं ने दो- तरीकों से पुष्टि करने की सुविधा सेट अप की है उनके लिए, हम यूज़र इंटरफ़ेस (यूआई) फ़्लो को अलग-अलग नहीं देखना चाहते. यह इस बात पर निर्भर करता है कि पासवर्ड सही था या नहीं. इसलिए, हम इस चरण में पासवर्ड और क्रेडेंशियल, दोनों की एक साथ जांच करते हैं.
  • अगर पासवर्ड और क्रेडेंशियल, दोनों मान्य हैं, तो हम completeAuthentication(req, res); व्यावहारिक तौर पर पुष्टि करने के लिए पुष्टि करते हैं. इसका मतलब है कि हम सेशन को कुछ समय के लिए auth सेशन में बदलते हैं. इसमें उपयोगकर्ता की पुष्टि अभी तक नहीं होती है. main उपयोगकर्ता के पुष्टि होने के मुख्य सेशन में स्विच किया जाता है.

उपयोगकर्ता के फ़्लो में, दो तरीकों से पुष्टि करने वाला पेज शामिल करें

views फ़ोल्डर में, नया पेज second-factor.html देखें.

इसमें एक ऐसा बटन है जो कहता है सुरक्षा कुंजी का इस्तेमाल करें, लेकिन अभी यह कुछ और #39;नहीं करता है.

क्लिक करने पर यह बटन authenticateTwoFactor() कॉल करें.

  • अगर authenticateTwoFactor() हो जाता है, तो उपयोगकर्ता को उनके खाता पेज पर रीडायरेक्ट करें.
  • अगर यह सफल नहीं होता, तो उपयोगकर्ता को गड़बड़ी होने की सूचना दें. एक असली ऐप्लिकेशन में, आप इस डेमो में आसानी के लिए, ज़्यादा उपयोगी गड़बड़ी के मैसेज को लागू करते हैं. इसलिए, हम सिर्फ़ # विंडो चेतावनी का इस्तेमाल करते हैं.
    <main>
...
    </main>
    <script type="module">
      import { authenticateTwoFactor, authStatuses } from "/auth.client.js";

      const button = document.querySelector("#authenticateButton");
      button.addEventListener("click", async e => {
        try {
          // Ask the user to authenticate with the second factor; this will trigger a browser prompt
          const response = await authenticateTwoFactor();
          const { authStatus } = response;
          if (authStatus === authStatuses.COMPLETE) {
            // The user is properly authenticated => Navigate to the Account page
            location.href = "/account";
          } else {
            throw new Error("Two-factor authentication failed");
          }
        } catch (e) {
          // Alert the user that something went wrong
          alert(`Two-factor authentication failed. ${e}`);
        }
      });
    </script>
  </body>
</html>

दो तरीकों से पुष्टि करने की सुविधा का इस्तेमाल करें

अब आप #39 सेकंड में, पुष्टि करने वाले दूसरे तरीके को जोड़ सकते हैं.

फ़िलहाल, आपको index.html से इस चरण को जोड़ना होगा. ऐसा उन उपयोगकर्ताओं के लिए करना होगा जिन्होंने दो तरीकों से पुष्टि करने की सुविधा को कॉन्फ़िगर किया है.

322a5c49d865a0d8.png

index.html में, location.href = "/account"; के नीचे, वह कोड जोड़ें जो उपयोगकर्ता को दूसरे फ़ैक्टर के पुष्टि करने वाले पेज पर तब भेजता है, जब वह 2FA सेट अप करता है.

इस कोडलैब (कोड बनाना सीखना) में, क्रेडेंशियल बनाने से उपयोगकर्ता अपने-आप दो तरीकों से पुष्टि करने की सुविधा के लिए ऑप्ट-इन हो जाता है.

ध्यान दें कि server.js में सर्वर-साइड सेशन की जांच भी की जाती है. इससे यह पक्का होता है कि सिर्फ़ पुष्टि किए गए उपयोगकर्ता ही account.html को ऐक्सेस कर सकते हैं.

const { authStatus } = response;
if (authStatus === authStatuses.COMPLETE) {
  // The user is properly authenticated => navigate to account
  location.href = '/account';
} else if (authStatus === authStatuses.NEED_SECOND_FACTOR) {
  // Navigate to the two-factor-auth page because two-factor-auth is set up for this user
  location.href = '/second-factor';
}

इसे आज़माएं! CANNOT TRANSLATE

  • नए उपयोगकर्ता johndoe से लॉग इन करें.
  • लॉग आउट करें.
  • अपने खाते में johndoe के तौर पर लॉग इन करें और देखें कि सिर्फ़ पासवर्ड डालना ज़रूरी है.
  • कोई क्रेडेंशियल बनाएं. इसका मतलब यह होगा कि आपने'दो तरीकों से पुष्टि करने की सुविधा को johndoe के तौर पर चालू कर दिया है.
  • लॉग आउट करें.
  • अपना उपयोगकर्ता नाम johndoe और पासवर्ड डालें.
  • देखें कि आप कैसे दो तरीकों से पुष्टि करने वाले पेज पर अपने-आप नेविगेट कर रहे हैं.
  • (खाता पेज को /account पर ऐक्सेस करें; ध्यान दें कि आपको #33;
  • दो तरीकों से पुष्टि करने के तरीके की पुष्टि करने वाले पेज पर वापस जाएं. इसके बाद, दूसरे तरीके से पुष्टि करने के लिए, सुरक्षा कुंजी का इस्तेमाल करें पर क्लिक करें.
  • अब आप लॉग इन हो गए हैं और आपको अपना खाता पेज दिखना चाहिए!

8. क्रेडेंशियल का इस्तेमाल करना आसान बनाएं

सुरक्षा कुंजी की मदद से, दो तरीकों से पुष्टि करने की सुविधा से जुड़ा बुनियादी काम पूरा किया गया है 🚀

लेकिन... क्या आपने ध्यान दिया?

इस समय, हमारी क्रेडेंशियल सूची बहुत सुविधाजनक नहीं है: क्रेडेंशियल आईडी और सार्वजनिक कुंजी लंबी स्ट्रिंग हैं, जो क्रेडेंशियल प्रबंधित करने में सहायता नहीं करती हैं! इंसानों में बहुत ज़्यादा लंबी स्ट्रिंग और नंबर होते हैं 📢 🤯

इसलिए, इसे बेहतर बनाने में मदद करें. साथ ही, क्रेडेंशियल को नाम देने और उनके नाम बदलने की सुविधा की मदद से, लोगों के लिए काम की स्ट्रिंग चुनें.

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

इस फ़ंक्शन को लागू करने में लगने वाला आपका समय बचाने के लिए, auth.client.js में, शुरुआती कोड में आपके लिए क्रेडेंशियल का नाम बदलने का एक फ़ंक्शन जोड़ा गया है:

async function renameCredential(credId, newName) {
  const params = new URLSearchParams({
    credId,
    name: newName
  });
  return _fetch(
    `/auth/credential?${params}`,
    "PUT"
  );
}

यह एक सामान्य डेटाबेस अपडेट कॉल है: क्लाइंट बैकएंड में एक PUT अनुरोध भेजता है, जिसमें एक क्रेडेंशियल आईडी और उस क्रेडेंशियल के लिए नया नाम शामिल होता है.

कस्टम क्रेडेंशियल के नाम लागू करना

account.html में, खाली फ़ंक्शन rename पर ध्यान दें.

इसे नीचे दिए गए कोड में जोड़ें:

// Rename a credential
async function rename(credentialId) {
  // Let the user input a new name
  const newName = window.prompt(`Name this credential:`);
  // Rename only if the user didn't cancel AND didn't enter an empty name
  if (newName && newName.trim()) {
    try {
      // Make the backend call to rename the credential (the name is sanitized) server-side
      await renameCredential(credentialId, newName);
    } catch (e) {
      // Alert the user that something went wrong
      if (Array.isArray(e)) {
        alert(
          // `msg` not `message`, this is the key's name as per the express validator API
          `Renaming failed. ${e.map((err) => `${err.msg} (${err.param})`)}`
        );
      } else {
        alert(`Renaming failed. ${e}`);
      }
    }
    // Refresh the credential list to display the new name
    await updateCredentialList();
  }
}

क्रेडेंशियल का नाम दिए जाने के बाद ही, क्रेडेंशियल को नाम देना ज़्यादा सही हो सकता है. इसलिए, बिना नाम वाला एक क्रेडेंशियल बनाएं. क्रेडेंशियल बनाने के बाद, क्रेडेंशियल का नाम बदलें. हालांकि, इससे दो बैकएंड कॉल होंगे.

रजिस्ट्रेशन के दौरान उपयोगकर्ताओं को क्रेडेंशियल नाम देने के लिए, register() में rename फ़ंक्शन का इस्तेमाल करें:

async function register() {
  let user = {};
  try {
    const user = await registerCredential();
    // Get the latest credential's ID (newly created credential)
    const allUserCredentials = user.credentials;
    const newCredential = allUserCredentials[allUserCredentials.length - 1];
    // Rename it
    await rename(newCredential.credId);
  } catch (e) {
    // ...
  }
  // Refresh the credential list to display the new credential
  await updateCredentialList();
}

ध्यान दें कि उपयोगकर्ता के इनपुट की पुष्टि की जाएगी और बैकएंड में इसकी अनुमति दी जाएगी:

  check("name")
    .trim()
    .escape()

क्रेडेंशियल के नाम दिखाएं

templates.js में getCredentialHtml की ओर जाएं.

ध्यान दें कि क्रेडेंशियल कार्ड में सबसे ऊपर, क्रेडेंशियल और #39; का नाम दिखाने के लिए यहां पहले से ही कोड मौजूद है:

// Register credential
const getCredentialHtml = (credential, removeEl, renameEl) => {
 const { name, credId, publicKey } = credential;
 return html`
    <div class="credential-card">
      <div class="credential-name">
        ${name
          ? html`
              ${name}
            `
          : html`
              <span class="unnamed">(Unnamed)</span>
            `}
      </div>
     // ...
    </div>
  `;
};

इसे आज़माएं! CANNOT TRANSLATE

  • कोई क्रेडेंशियल बनाएं.
  • आपको इसे नाम देने के लिए कहा जाएगा.
  • नया नाम डालें और ठीक है पर क्लिक करें.
  • क्रेडेंशियल का नाम अब बदल दिया गया है.
  • दोहराएं और नाम फ़ील्ड को खाली छोड़े जाने पर यह भी जांच करें कि चीज़ें ठीक से काम कर रही हैं या नहीं.

क्रेडेंशियल का नाम बदलने की सुविधा चालू करें

उपयोगकर्ताओं को क्रेडेंशियल का नाम बदलना पड़ सकता है–उदाहरण के लिए, वे एक और कुंजी जोड़ रहे हैं और अपनी पहली कुंजी का नाम बदलना चाहते हैं, ताकि वे बेहतर तरीके से पहचान सकें.

account.html में, यहां तक के खाली फ़ंक्शन renameEl को खोजें और उसे इस कोड में जोड़ें:

// Rename a credential via HTML element
async function renameEl(el) {
  // Define the ID of the credential to update
  const credentialId = el.srcElement.dataset.credentialId;
  // Rename the credential
  await rename(credentialId);
  // Refresh the credential list to display the new name
  await updateCredentialList();
}

अब, templates.js's के getCredentialHtml में class="flex-end" div के अंदर, यह कोड जोड़ें. यह कोड क्रेडेंशियल वाले कार्ड के टेम्प्लेट में नाम बदलें बटन जोड़ता है; इस बटन पर क्लिक करने से, यह renameEl फ़ंक्शन को कॉल कर देगा जिसे हमने अभी-अभी बनाया है:

const getCredentialHtml = (credential, removeEl, renameEl) => {
// ...
 <div class="flex-end">
  <button
    data-credential-id="${credId}"
    @click="${renameEl}"
    class="secondary right"
  >
   Rename
  </button>
 </div>
 // ...
  `;
};

इसे आज़माएं! CANNOT TRANSLATE

  • नाम बदलें पर क्लिक करें.
  • कहे जाने पर एक नया नाम डालें.
  • ठीक है पर क्लिक करें.
  • क्रेडेंशियल का नाम सफलतापूर्वक बदला जाना चाहिए और सूची अपने-आप अपडेट हो जानी चाहिए.
  • पेज को फिर से लोड करने से अब भी नया नाम दिखना चाहिए. इससे पता चलता है कि नया नाम, सर्वर के साथ-साथ पहले जैसा ही दिख रहा है.

क्रेडेंशियल बनाने की तारीख दिखाएं

बनाने की तारीख navigator.credential.create() के ज़रिए बनाए गए क्रेडेंशियल में मौजूद नहीं है.

हालांकि, यह जानकारी उपयोगकर्ता के लिए क्रेडेंशियल के बीच अंतर करने में काम की हो सकती है, इसलिए हमने आपके लिए स्टार्टर कोड में सर्वर-साइड लाइब्रेरी में बदलाव किया है. साथ ही, नए क्रेडेंशियल सेव करने के बाद, creationDate फ़ील्ड को Date.now() के बराबर जोड़ दिया है.

templates.js में class="creation-date" div के अंदर, उपयोगकर्ता को बनाने की तारीख से जुड़ी जानकारी दिखाने के लिए यह जानकारी जोड़ें:

<div class="creation-date">
  <label>Created:</label>
  <div class="info">
    ${new Date(creationDate).toLocaleDateString()}
    ${new Date(creationDate).toLocaleTimeString()}
  </div>
</div>

9. अपने कोड को आने वाले समय के लिए आसान बनाना

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

एक और बेहतर तरीका है, ज़्यादा पुष्टि करने वाले तरीके से पुष्टि करना: उपयोगकर्ता की पुष्टि करने वाला रोमिंग ऑथेंटिकेशन (यूवीआरए). यूवीआरए से दो चरणों में पुष्टि करने की प्रक्रिया का पता चलता है और एक ही चरण में साइन इन करने पर, फ़िशिंग का असर पड़ता है.

आम तौर पर, आप दो तरीकों से काम करते हैं. ऐसा करने के लिए, आपको उपयोगकर्ता अनुभव को अपनी पसंद के मुताबिक बनाना होगा:

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

इसके बारे में ज़्यादा जानने के लिए, बिना पासवर्ड के साइन इन करने के लिए फ़िशिंग से बचने के लिए खाते का बूटस्ट्रैपिंग पर जाएं.

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

आपको दो चीज़ों की ज़रूरत होगी:

  • अपने बैकएंड की सेटिंग में residentKey: preferred सेट करें. यह आपके लिए पहले ही किया जा चुका है.
  • यह पता लगाने का एक तरीका सेट अप करें कि खोजे जाने लायक क्रेडेंशियल (जिसे रेज़िडेंट कुंजी भी कहा जाता है) बनाया गया था या नहीं.

यह पता लगाने के लिए कि खोजा जा सकने वाला क्रेडेंशियल बनाया गया है या नहीं:

  • क्रेडेंशियल बनाने पर (credProps: true) credProps के मान पर क्वेरी करें.
  • क्रेडेंशियल बनाने पर transports की वैल्यू की क्वेरी करें. इससे आपको यह तय करने में मदद मिलेगी कि दिया गया प्लैटफ़ॉर्म यूवीआरए फ़ंक्शन को सपोर्ट करता है या नहीं. उदाहरण के लिए, यह मोबाइल फ़ोन है या नहीं.
  • बैकएंड में credProps और transports की वैल्यू स्टोर करें. आप स्टार्टर कोड में यह कर चुके हैं. अगर आप यह जानने के लिए उत्सुक हैं तो #auth.js देखें.

आइए credProps और transports की वैल्यू पाएं और उन्हें बैकएंड में भेजें. auth.client.js में, registerCredential को इस तरह बदलें:

  • navigator.credentials.create को कॉल करने पर extensions फ़ील्ड जोड़ें
  • स्टोरेज के लिए बैकएंड में क्रेडेंशियल भेजने से पहले encodedCredential.transports और encodedCredential.credProps सेट करें.

registerCredential ऐसा दिखना चाहिए:

async function registerCredential() {
  // Fetch the credential creation options from the backend
  const credentialCreationOptionsFromServer = await _fetch(
    '/auth/credential-options',
    'POST'
  );
  // Decode the credential creation options
  const credentialCreationOptions = decodeServerOptions(
    credentialCreationOptionsFromServer
  );
  // Create a credential via the browser API; this will prompt the user
  const credential = await navigator.credentials.create({
    publicKey: {
      ...credentialCreationOptions,
      extensions: {
        credProps: true,
      },
    },
  });
  // Encode the newly created credential to send it to the backend
  const encodedCredential = encodeCredential(credential);
  // Set transports and credProps for more advanced user flows
  encodedCredential.transports = credential.response.getTransports();
  encodedCredential.credProps =
    credential.getClientExtensionResults().credProps;
  // Send the encoded credential to the backend for storage
  return await _fetch('/auth/credential', 'POST', encodedCredential);
}

10. क्रॉस-ब्राउज़र सहायता पक्का करना

गैर-Chromium ब्राउज़र के साथ काम करना

public/auth.client.js's registerCredential फ़ंक्शन में, हम नए क्रेडेंशियल पर credential.response.getTransports() को कॉल कर रहे हैं, ताकि सर्वर के लिए संकेत के तौर पर बैकएंड में इस जानकारी को सेव किया जा सके.

हालांकि, फ़िलहाल getTransports() को सभी ब्राउज़र में लागू नहीं किया जाता (जबकि ब्राउज़र में यह सुविधा काम नहीं करती): getTransports() कॉल Firefox और Safari में एक गड़बड़ी दिखाएगा, जिससे इन ब्राउज़र में क्रेडेंशियल बनाने की अनुमति नहीं मिलेगी.

यह पक्का करने के लिए कि आपका कोड सभी प्रमुख ब्राउज़र पर काम करे, encodedCredential.transports कॉल को शर्त में रैप करें:

if (credential.response.getTransports) {
  encodedCredential.transports = credential.response.getTransports();
}

ध्यान दें कि सर्वर पर, transports transports || [] पर सेट है. Firefox और Safari में transports सूची undefined नहीं होगी, बल्कि खाली सूची [] होगी, जो गड़बड़ियों को रोकती है.

उन उपयोगकर्ताओं को चेतावनी दें जो WebAuthn के साथ काम न करने वाले ब्राउज़र का इस्तेमाल करते हैं

1e9c1be837d66ce8.png

हालांकि, WebAuthn सभी प्रमुख ब्राउज़र में काम करता है, लेकिन फिर भी यह उन ब्राउज़र में चेतावनी दिखाता है जो WebAuthn के साथ काम नहीं करते.

index.html में, इस div की मौजूदगी पर नज़र रखें:

<div id="warningbanner" class="invisible">
⚠️ Your browser doesn't support WebAuthn. Open this demo in Chrome, Edge, Firefox or Safari.
</div>

index.html's की स्क्रिप्ट के साथ-साथ, इन कोड को ऐसे ब्राउज़र में दिखाने के लिए जोड़ें जो WebAuthn के साथ काम नहीं करते:

// Display a banner in browsers that don't support WebAuthn
if (!window.PublicKeyCredential) {
  document.querySelector('#warningbanner').classList.remove('invisible');
}

किसी असली वेब ऐप्लिकेशन में, आप कुछ और बेहतर काम करते हैं और आपके पास इन ब्राउज़र के लिए एक सही फ़ॉलबैक मैकेनिज़्म होता है. हालांकि, यह आपको WebAuthn सहायता की जांच करने का तरीका दिखाता है.

11. बहुत खूब!

✨आप #39;हो गए!

आपने सुरक्षा कुंजी से दो तरीकों से पुष्टि करने की सुविधा को लागू किया है.

इस कोडलैब में हमने #39 बुनियादी बातों पर चर्चा की है. अगर आपको 2FA के लिए WebAuthn एक्सप्लोर करना है, तो यहां कुछ आइडिया दिए गए हैं जिन्हें आप आगे आज़मा सकते हैं:

  • क्रेडेंशियल में पिछली बार इस्तेमाल किए गए &कोटेशन की जानकारी जोड़ें. यह उपयोगकर्ताओं के लिए इस बात का पता लगाने के लिए उपयोगी जानकारी देता है कि दी गई सुरक्षा कुंजी का इस्तेमाल किया जा रहा है या नहीं—खास तौर पर तब, जब उन्होंने कई कुंजियां रजिस्टर की हों.
  • गड़बड़ी को ज़्यादा बेहतर तरीके से हैंडल करने और गड़बड़ी के ज़्यादा सटीक मैसेज को लागू करें.
  • auth.js में देखें और जानें कि जब आप authSettings में से कुछ बदलते हैं, तो क्या होता है. खास तौर पर, जब आप किसी ऐसी कुंजी का इस्तेमाल करते हैं जिससे Google की पुष्टि की जा सकती है.