Implementing Passkeys & WebAuthn in Modern Web Applications

Passkeys replace phishing-prone passwords with cryptographic public-key pairs bound to biometric hardware. Here is a practical engineering guide to implementing WebAuthn registration and authentication in web applications.

The Flaws of Shared Secrets & SMS 2FA

For decades, web authentication has relied on shared secrets: passwords stored in databases (hopefully hashed with Argon2 or bcrypt) and shared with the server over TLS. Despite security awareness, password reuse, credential stuffing attacks, phishing kits, and SIM-swapping remain responsible for over 80% of corporate data breaches.

Passkeys—built on the W3C WebAuthn and FIDO2 standards—fundamentally eliminate shared secrets. Instead of sending a password over the wire, authentication uses asymmetric public-key cryptography. The user's device (Apple TouchID, Windows Hello, Android Biometrics, or a hardware YubiKey) generates a unique cryptographic keypair: the public key is stored on your server, while the private key never leaves the device's secure hardware enclave.

1. The WebAuthn Cryptographic Protocol

WebAuthn authentication proceeds through a two-step cryptographic challenge-response exchange:

  1. Challenge Dispatch: When a user enters their email or username, the server generates a cryptographically random, one-time 32-byte challenge and returns it along with the relying party ID (rpId = "devmanue.com").
  2. Hardware Signature: The browser calls the native WebAuthn API: navigator.credentials.get(). The user touches their fingerprint sensor or FaceID camera. The hardware enclave signs the challenge using the private key.
  3. Cryptographic Verification: The browser returns the signed assertion (authenticator data, client data JSON, and cryptographic signature). The server verifies the signature against the stored public key using standard elliptic curve algorithms (ES256 / Ed25519). If valid, a session is issued.

2. Browser Client Flow: Registering a New Passkey

On the frontend, initiating passkey registration requires zero third-party dependencies; it uses the native browser PublicKeyCredential API:

// Initiate registration from frontend
async function registerPasskey() {
  // 1. Fetch challenge from Django backend
  const response = await fetch('/api/auth/passkey/register/options/');
  const options = await response.json();

  // 2. Decode base64url challenge and user ID buffers
  options.challenge = Uint8Array.from(atob(options.challenge), c => c.charCodeAt(0));
  options.user.id = Uint8Array.from(atob(options.user.id), c => c.charCodeAt(0));

  // 3. Prompt user for biometric / hardware credential
  try {
    const credential = await navigator.credentials.create({ publicKey: options });
    
    // 4. Send public key credential back to server for storage
    await fetch('/api/auth/passkey/register/verify/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        id: credential.id,
        rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
        response: {
          clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(credential.response.clientDataJSON))),
          attestationObject: btoa(String.fromCharCode(...new Uint8Array(credential.response.attestationObject)))
        }
      })
    });
    alert("Passkey successfully registered!");
  } catch (err) {
    console.error("Passkey registration rejected:", err);
  }
}

3. Why Passkeys are Completely Immune to Phishing

The most profound architectural breakthrough of WebAuthn is cryptographic origin binding. When the browser executes navigator.credentials.get(), the operating system itself determines the effective origin (e.g. https://devmanue.com) and passes it directly to the hardware enclave.

If an employee is tricked into visiting a pixel-perfect phishing site like https://devmanue.phishing-clone.com, the browser sends the phishing domain to the security key. The key checks its internal vault, discovers no credential registered for that domain, and refuses to sign. The phisher captures zero credentials because no shared secret exists to steal.

"Passkeys render phishing mathematically impossible. You cannot steal what was never transmitted."
Architectural Continuity & Deep Dives

For related production architectures and system implementations, explore these companion guides:

Key Architectural Takeaways

Implementing Passkeys transitions your application from legacy shared passwords to asymmetric cryptographic zero-trust authentication. By pairing native browser WebAuthn APIs with robust public-key storage, you deliver instant biometric logins for your users while immunizing your infrastructure against credential stuffing and phishing threats.

All Insights
Chat on WhatsApp