पासकी की मदद से फिर से पुष्टि करना

वेब की सुविधाएं: वेब पर पुष्टि करना

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

डेल्टा फ़्लो आर्किटेक्चर

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

सर्वर-साइड

विकल्प जनरेट करने की सुविधा में बदलाव

एक ऐसा एंडपॉइंट बनाएं जो खास तौर पर, ऐक्टिव और जाने-पहचाने उपयोगकर्ता के लिए, अनुमति वाले क्रेडेंशियल पैरामीटर को पॉप्युलेट करे:

क्रेडेंशियल पर पाबंदी लगाना: साइन इन किए हुए उपयोगकर्ता के लिए, रजिस्टर किए गए सभी क्रेडेंशियल आईडी को मैप करने वाले खास PublicKeyCredentialDescriptor रिकॉर्ड के साथ, allowCredentials विकल्प कलेक्शन को पॉप्युलेट करें. इस फ़ील्ड को खाली छोड़ने या इसमें कोई वैल्यू न डालने पर, खोजे जा सकने वाले क्रेडेंशियल का इस्तेमाल किया जाता है. इससे सेशन की सुरक्षा से जुड़ी नीति का उल्लंघन होता है.

// Node.js step-up options generation example
router.post("/api/reauth/options", enforceActiveSession, async (req, res) => {
  const userPasskeys = await db.findCredentialsByUserId(req.user.id);

  const options = {
    challenge: serverGeneratedBase64UrlChallenge, // Random challenge stored in user session
    rpId: "example.com",
    // Enforce allowance strictly limited to the user's credentials list
    allowCredentials: userPasskeys.map((cred) => ({
      type: "public-key",
      id: cred.id,
      transports: cred.transports, // Speeds up resolution by indicating platform transports
    })),
  };
  return res.json(options);
});

पुष्टि करने के एंडपॉइंट का डेल्टा

क्लाइंट से मिले दावे की पुष्टि करें:

खाते के मालिकाना हक की पुष्टि करना: पुष्टि करने वाले एंडपॉइंट को साफ़ तौर पर यह पुष्टि करनी होगी कि क्लाइंट से मिला क्रेडेंशियल आईडी, सेव किए गए क्रेडेंशियल रिकॉर्ड से मैच करता हो. साथ ही, उस क्रेडेंशियल रिकॉर्ड से जुड़ा यूज़र आईडी, साइन इन किए हुए ऐक्टिव उपयोगकर्ता (storedCredential.passkeyUserId === req.user.id) से पूरी तरह मैच करता हो. अगर किसी दूसरे उपयोगकर्ता की मान्य पासकी मिलती है, तो पुष्टि करने की प्रोसेस को तुरंत अस्वीकार कर दिया जाना चाहिए.

क्लाइंट-साइड फ़्लो डेल्टा

लेन-देन के यूज़र इंटरफ़ेस (यूआई) के आधार पर, ऐप्लिकेशन फिर से पुष्टि करने के लिए दो इंटरफ़ेस में से किसी एक को चुनते हैं:

A. बटन फ़्लो (कोई इनपुट फ़ील्ड नहीं)

जब कोई उपयोगकर्ता "पहचान की पुष्टि करें" या "लेन-देन जारी रखें" बटन दबाए, तो फिर से पुष्टि करने की प्रोसेस को ट्रिगर करें.

<button id="reauth-btn" data-testid="reauth-button">Confirm Transaction</button>
let reauthAbortController = new AbortController();

async function triggerButtonReauth() {
  // Abort any background suggestion flows to avoid passkey prompt collisions
  reauthAbortController.abort();
  reauthAbortController = new AbortController();

  const optionsResponse = await fetch("/api/reauth/options", {
    method: "POST",
  });
  const optionsJSON = await optionsResponse.json();
  const publicKey =
    PublicKeyCredential.parseRequestOptionsFromJSON(optionsJSON);

  try {
    const credential = await navigator.credentials.get({
      publicKey,
      signal: reauthAbortController.signal,
    });

    if (credential) {
      const encodedCredential = credential.toJSON();
      const verifyResponse = await fetch("/api/reauth/verify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(encodedCredential),
      });

      if (verifyResponse.ok) {
        showTransactionSuccessUI();
      } else if (verifyResponse.status === 404 && PublicKeyCredential.signalUnknownCredential) {
        await PublicKeyCredential.signalUnknownCredential({
          rpId, // RP ID must match the one defined on the server
          credentialId: encodedCredential.id
        });
      }
    }
  } catch (err) {
    if (err.name === "NotAllowedError") {
      console.log("User cancelled reauthentication.");
    }
  }
}

document
  .getElementById("reauth-btn")
  .addEventListener("click", triggerButtonReauth);

फ़ॉलबैक रणनीतियां

पासकी की सुविधा का पता लगाने के लिए फ़ॉलबैक

हमेशा 'webauthn-polyfills' इंस्टॉल करें और उसे कॉन्टेक्स्ट में इंपोर्ट करें. ध्यान रखें कि जब तक PublicKeyCredential का इस्तेमाल किया जा सकता है, तब तक PublicKeyCredential.getClientCapabilities का भी इस्तेमाल किया जा सकता है.

import 'webauthn-polyfills';

Easy JSON Serialization Fallback

हमेशा 'webauthn-polyfills' इंस्टॉल करें और उसे कॉन्टेक्स्ट में इंपोर्ट करें. ध्यान रखें कि जब तक PublicKeyCredential का इस्तेमाल किया जा सकता है, तब तक PublicKeyCredential.parseRequestOptionsFromJSON और PublicKeyCredential.prototype.toJSON का भी इस्तेमाल किया जा सकता है.

import 'webauthn-polyfills';