Skip to content
Node-devs logo

Blog

How to Add Passkey Login to Your Website or App (Developer Guide)

Want passwordless login on your site? This guide covers the WebAuthn registration and sign-in flows, server checks, recovery planning and the pitfalls that trip teams up.

Rafiq Hasan 4 min read
Share
Add passkey login to a website - shield with checkmark
Table of contents
  1. Key takeaways
  2. The Moving Parts
  3. Registration Flow
  4. Sign-In Flow
  5. Server-Side Checks That Matter
  6. Design Decisions
  7. Common Pitfalls
  8. Security Checklist Before Launch
  9. Build or Buy?
  10. References and further reading

Passkeys are no longer experimental, and users are starting to expect them. The good news for developers is that you do not have to rebuild your authentication: passkeys can sit next to your existing login. We compared implementation guidance from Google, Yubico and Authgear, plus the FIDO Alliance's overview, and merged their advice into one walkthrough. (New to the topic? Start with what passkeys are.)

Key takeaways

  • Passkeys use the WebAuthn browser API: navigator.credentials.create() to register and navigator.credentials.get() to sign in.
  • Your server issues single-use random challenges and verifies the signed responses. Use a maintained library for that part.
  • Keep passwords as a fallback at first, and design recovery before launch.
  • HTTPS is required, and the relying-party ID must match your domain.

The Moving Parts

Google's developer guide names three components: the relying party (your client and server, which store and verify credentials), the user's authenticator (phone, laptop or security key that creates and checks the passkey using the screen lock) and optionally a password manager that stores and syncs passkeys. Yubico adds that the relying party manages credentials, issues and verifies challenges and grants access according to your security policy. Your credential store holds, for each passkey, the public key, the credential ID and the user handle. Because private keys stay on the authenticator, a leaked credential table gives an attacker little they can use, a big improvement over a leaked password database.

Registration Flow

  1. The signed-in user (or new account) chooses "Add a passkey".
  2. Your server generates a random challenge and returns creation options: your RP ID (your domain), a stable user ID, username and display name. Include the user's existing credential IDs so a device does not register twice.
  3. The browser calls navigator.credentials.create(). The user approves with biometrics or a PIN.
  4. The client sends the new credential back. Your server verifies the challenge, origin and RP ID, then stores the credential ID, public key and signature counter against the user.

Sign-In Flow

  1. The server issues a fresh challenge (this blocks replay attacks).
  2. The browser calls navigator.credentials.get() and the user unlocks the passkey.
  3. The server looks up the credential by ID, checks the user handle against the account, verifies the signature with the stored public key and updates the counter.
  4. On success, create the session.

Yubico's guidance stores a user handle alongside each credential; match on that stable handle rather than on the username, which can change. Offering passkeys through browser autofill (conditional UI) makes adoption smoother, because users see their passkey in the username field.

Server-Side Checks That Matter

  • Use a library. Both Google and Authgear advise using an established open-source WebAuthn library instead of writing the cryptography yourself.
  • Challenges: generate them with a secure random generator (at least 16 bytes; 32 is better), make each one single-use and expire it within minutes.
  • RP ID and origin: confirm they match your real domain.
  • Signature counter: store it. A counter lower than the stored value can indicate a cloned authenticator, so require re-authentication.
  • Attestation: set it to none unless you truly need to restrict authenticator models. Direct attestation triggers extra consent prompts on some platforms; Yubico covers attestation separately for high-assurance cases.

Design Decisions

  • Keep existing methods. Google recommends leaving current sign-in options in place while the ecosystem matures, and strengthening them meanwhile with password-manager-friendly forms and one-time codes. Treat emailed magic links with caution because they depend on email security.
  • Multiple passkeys per account. Let users name, add and remove them. Encourage at least two devices, or a synced passkey plus a hardware key.
  • Recovery. Authgear's advice is blunt: plan it before launch, or locked-out users become support tickets. Offer verified email recovery or backup codes.
  • Step-up for risky actions. Ask for the passkey again before changing email, payment details or security settings.
  • Clear UX. Follow the FIDO Alliance's guidelines for creating and signing in with passkeys and give users a simple page to manage them.

Common Pitfalls

  • Passing raw strings instead of buffers to the WebAuthn API makes create() throw. Decode base64url values first.
  • A mismatched RP ID, or serving the page over plain HTTP (only localhost is exempt), stops credentials from being accepted.
  • Restricting the authenticator type to "platform" excludes hardware security keys.
  • Windows Hello credentials are bound to the device and do not sync, so a new PC needs re-registration.
  • Native apps need domain association: Digital Asset Links on Android, an apple-app-site-association file on iOS. Android debug and release builds use different signing keys, and iOS caches the association file for up to a day.

Security Checklist Before Launch

  • HTTPS everywhere, strict origin and RP ID validation.
  • Rate limiting and logging on authentication endpoints.
  • Tested recovery for a lost device.
  • Tested on real phones, laptops and a hardware key, not only simulators.
  • A security review of the whole login flow; see cybersecurity threats for small business.

Build or Buy?

If authentication is not your product, a hosted identity provider or a well-maintained library saves time and reduces risk. Google notes you can also delegate both ceremonies to an identity provider and receive the result over standard OpenID Connect. If you have a custom platform, a tailored integration may fit better. Node-devs can help you plan and implement passwordless login end to end.

References and further reading

This guide was compiled from the sources below. We compared them, kept the points they agree on and wrote the article in our own words. Check the originals for more detail.

  1. Passkeys developer guides (Google for Developers)
  2. Passkey relying party implementation guidance (Yubico)
  3. How to implement passkeys with WebAuthn: complete developer guide (Authgear)
  4. Passkeys (FIDO Alliance)

Frequently asked questions

Do I need to remove passwords to support passkeys?+

No. Google's guidance is to keep existing sign-in methods for now and add passkeys alongside them, because some users have incompatible devices or are not ready to switch.

Should I write the WebAuthn verification myself?+

No. Use a maintained server library or a hosted identity provider. The browser calls are simple, but verifying responses incorrectly can create serious security holes.

What should I store for each passkey?+

The credential ID, the public key, the user handle and the signature counter, linked to the user account. Private keys never reach your server.

How do I handle lost devices?+

Plan recovery before launch: encourage at least two registered passkeys or devices and offer verified alternatives such as email verification or backup codes.

Rafiq Hasan

Written by

Rafiq Hasan

Full-Stack Developer

Rafiq writes practical guides on Node.js, TypeScript and shipping software, with a focus on developers starting out in South Asia.

Related Articles

Get practical tech insights, monthly

One email a month with our best guides on software, AI and growth. No spam - unsubscribe any time.

Contact Our Team

We pride ourselves staying at the front of innovation, constantly pushing boundaries - shaping the Digital World Together and redefining what's possible.

To More Inquiry

+8801867748073

To Send Mail

info@node-devs.com

Your Success Starts Here!

Protected by reCAPTCHA & honeypot spam filtering.

Add Passkey Login to Your Website: WebAuthn Guide