Implementing Passwordless Authentication
1. Understanding Passwordless Concepts
| Method | Factor Used | Phish-Resistant? |
|---|---|---|
| Magic link | Email possession | Partial |
| SMS code | Phone possession | No (SIM swap) |
| WebAuthn / Passkeys | Device key + biometric | Yes |
| Hardware key | Possession + PIN | Yes |
| Biometric only | Inherence (device-bound) | Yes |
2. Implementing Magic Links
Magic Link Flow
- User enters email
- Generate token (32 bytes), store hash + expiry (10 min)
- Email link:
https://app/auth/verify?t=<raw> - User clicks → server verifies + consumes token
- Issue session/JWT → redirect to app
- Bind token to originating IP/UA to prevent forwarding
3. Implementing WebAuthn
Example: Browser registration
const cred = await navigator.credentials.create({
publicKey: {
challenge: base64url.decode(serverChallenge),
rp: { id: "example.com", name: "Acme" },
user: { id: userIdBytes, name: "alice@x.com", displayName: "Alice" },
pubKeyCredParams: [{ type: "public-key", alg: -7 }, { alg: -257 }],
authenticatorSelection: { residentKey: "required", userVerification: "preferred" },
attestation: "none"
}
});
// POST cred to /webauthn/register/finish → server verifies + stores publicKey
| Algorithm | COSE ID |
|---|---|
| ES256 (recommended) | -7 |
| RS256 | -257 |
| EdDSA | -8 |
4. Using Biometric Authentication
| Where Used | Stack |
|---|---|
| Native iOS | LocalAuthentication framework |
| Native Android | BiometricPrompt API |
| Web | WebAuthn platform authenticator (Touch ID, Hello, Android) |
| Storage | Private key in Secure Enclave / StrongBox / TPM |
5. Implementing SMS Magic Codes
| Aspect | Detail |
|---|---|
| Code | 6 digits |
| Validity | 5 min |
| Autofill (iOS) | Append @example.com #123456 |
| Autofill (Android) | App-signature hash in message |
6. Using Hardware Security Keys
| Connector | Use |
|---|---|
| USB-A / USB-C | Desktop, laptop |
| NFC | Mobile (Android, iOS) |
| Lightning | iPhone (older) |
| Bluetooth | Multi-device (less common) |
| Protocol | FIDO2 (CTAP2) + WebAuthn |
7. Implementing Passkeys
| Aspect | Detail |
|---|---|
| Definition | FIDO2 discoverable credential synced across devices |
| Sync | iCloud Keychain, Google Password Manager, 1Password, Bitwarden |
| UX | Username field shows passkey suggestion (Conditional UI) |
| Server | Standard WebAuthn — same code path |
| Cross-device | QR + Bluetooth handoff (hybrid transport) |
| Replaces | Passwords + TOTP in single phish-resistant flow |
8. Handling Device Registration Flow
Passkey Registration
- Authenticate user with existing factor (or after signup)
- Server generates challenge (32 bytes), stores in session
- Send
PublicKeyCredentialCreationOptionsto client - Client invokes
navigator.credentials.create()— user authorizes via biometric - Client returns attestation + public key to server
- Server verifies challenge, origin (RP ID), signature
- Store credentialId + publicKey + signCount + AAGUID
9. Implementing Fallback Mechanisms
| Primary | Fallback |
|---|---|
| Passkey | Magic link to verified email |
| WebAuthn key | Backup codes |
| Biometric | Device PIN |
| All factors lost | Identity proofing (ID verification) |