What is @simplewebauthn/browser?
@simplewebauthn/browser is a JavaScript library that provides a simple interface for implementing WebAuthn (Web Authentication) in web applications. It allows developers to easily integrate passwordless authentication and second-factor authentication using hardware security keys, biometric sensors, and other authenticators that support the WebAuthn standard.
What are @simplewebauthn/browser's main functionalities?
Registration
This feature allows users to register a new authenticator (e.g., a security key or biometric device) with the web application. The code sample demonstrates how to start the registration process, send the registration options to the client, and verify the registration response on the server.
const { startRegistration } = require('@simplewebauthn/browser');
async function register() {
const options = await fetch('/generate-registration-options').then(res => res.json());
const attResp = await startRegistration(options);
const verification = await fetch('/verify-registration', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(attResp),
}).then(res => res.json());
if (verification.verified) {
console.log('Registration successful!');
} else {
console.log('Registration failed.');
}
}
Authentication
This feature allows users to authenticate using a previously registered authenticator. The code sample demonstrates how to start the authentication process, send the authentication options to the client, and verify the authentication response on the server.
const { startAuthentication } = require('@simplewebauthn/browser');
async function authenticate() {
const options = await fetch('/generate-authentication-options').then(res => res.json());
const assertionResp = await startAuthentication(options);
const verification = await fetch('/verify-authentication', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(assertionResp),
}).then(res => res.json());
if (verification.verified) {
console.log('Authentication successful!');
} else {
console.log('Authentication failed.');
}
}
Other packages similar to @simplewebauthn/browser
fido2-lib
fido2-lib is a comprehensive library for implementing FIDO2 and WebAuthn server-side functionality. It provides tools for generating and verifying registration and authentication data. Compared to @simplewebauthn/browser, fido2-lib focuses more on the server-side implementation and offers more granular control over the WebAuthn process.
webauthn
webauthn is a library that provides utilities for implementing WebAuthn in web applications. It includes both client-side and server-side components. While it offers similar functionalities to @simplewebauthn/browser, it may require more configuration and setup to get started.
passport-fido2
passport-fido2 is a Passport.js strategy for FIDO2 authentication. It integrates with the Passport.js authentication middleware for Node.js, making it easy to add FIDO2 authentication to existing Passport.js-based applications. Unlike @simplewebauthn/browser, which is focused on client-side interactions, passport-fido2 is designed for server-side integration with Passport.js.
@simplewebauthn/browser
Installation
This package is available on npm:
npm install @simplewebauthn/browser
UMD
This package can also be installed via unpkg by including the following script in your page's
<head>
element. The library's methods will be available on the global SimpleWebAuthnBrowser
object.
NOTE: The only difference between the two packages below is that the ES5 bundle includes
TypeScript's tslib
runtime code. This adds some bundle size overhead, but does enable use of
supportsWebAuthn()
in older browsers to show appropriate UI when WebAuthn is unavailable.
ES5
If you need to support WebAuthn feature detection in deprecated browsers like IE11 and Edge Legacy,
include the ES5
version:
<script src="https://unpkg.com/@simplewebauthn/browser/dist/bundle/index.es5.umd.min.js"></script>
ES2018
If you only need to support modern browsers, include the ES2018
version:
<script src="https://unpkg.com/@simplewebauthn/browser"></script>
Usage
You can find in-depth documentation on this package here:
https://simplewebauthn.dev/docs/packages/browser
v10.0.0 - The one that goes up to 20
Thanks for everything, Node 16 and Node 18, but it's time to move on! The headlining change of this
release is the targeting of Node LTS v20+ as the minimum Node runtime. Additional developer-centric
quality-of-life changes have also been made in the name of streamlining use of SimpleWebAuthn on
both the back end and front end.
This release is packed with updates, so buckle up! Refactor advice for breaking changes is, as
always, offered below.
Packages
- @simplewebauthn/browser@10.0.0
- @simplewebauthn/server@10.0.0
- @simplewebauthn/types@10.0.0
Changes
- [server] The minimum supported Node version has been raised to Node v20
(#531)
- [server]
user.displayName
now defaults to an empty string if a value is not specified for
userDisplayName
when calling generateRegistrationOptions()
(#538) - [browser] The
browserSupportsWebAuthnAutofill()
helper will no longer break in environments
in which PublicKeyCredential
is not present
(#557, with thanks to @clarafitzgerald)
Breaking Changes
- [server] The following breaking changes were made in PR
#529:
generateRegistrationOptions()
now expects Base64URLString
for excluded credential IDsgenerateAuthenticationOptions()
now expects Base64URLString
for allowed credential IDscredentialID
returned from response verification methods is now a Base64URLString
AuthenticatorDevice.credentialID
is now a Base64URLString
isoBase64URL.isBase64url()
is now called isoBase64URL.isBase64URL()
- [browser, server] The following breaking changes were made in PR
#552:
generateRegistrationOptions()
now accepts an optional Uint8Array
instead of a string
for
userID
isoBase64URL.toString()
and isoBase64URL.fromString()
have been renamedgenerateRegistrationOptions()
will now generate random user IDsuser.id
is now treated like a base64url string in startRegistration()
userHandle
is now treated like a base64url string in startAuthentication()
- [server]
rpID
is now a required argument when calling generateAuthenticationOptions()
(#555)
[server] generateRegistrationOptions()
now expects Base64URLString
for excluded credential IDs
The isoBase64URL
helper can be used to massage Uint8Array
credential IDs into base64url strings:
Before
const opts = await generateRegistrationOptions({
// ...
excludeCredentials: devices.map((dev) => ({
id: dev.credentialID, // type: Uint8Array
type: 'public-key',
transports: dev.transports,
})),
});
After
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const opts = await generateRegistrationOptions({
// ...
excludeCredentials: devices.map((dev) => ({
id: isoBase64URL.fromBuffer(dev.credentialID), // type: string
transports: dev.transports,
})),
});
The type
argument is no longer needed either.
[server] generateAuthenticationOptions()
now expects Base64URLString
for allowed credential IDs
Similarly, the isoBase64URL
helper can also be used during auth to massage Uint8Array
credential
IDs into base64url strings:
Before
const opts = await generateAuthenticationOptions({
// ...
allowCredentials: devices.map((dev) => ({
id: dev.credentialID, // type: Uint8Array
type: 'public-key',
transports: dev.transports,
})),
});
After
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const opts = await generateAuthenticationOptions({
// ...
allowCredentials: devices.map((dev) => ({
id: isoBase64URL.fromBuffer(dev.credentialID), // type: Base64URLString (a.k.a string)
transports: dev.transports,
})),
});
The type
argument is no longer needed either.
[server] credentialID
returned from response verification methods is now a Base64URLString
It is no longer necessary to manually stringify credentialID
out of response verification methods:
Before
import { isoBase64URL } from '@simplewebauthn/server/helpers';
// Registration
const { verified, registrationInfo } = await verifyRegistrationResponse({ ... });
if (verified && registrationInfo) {
const { credentialID } = registrationInfo;
await storeInDatabase({ credIDString: isoBase64URL.fromBuffer(credentialID), ... });
}
// Authentication
const { verified, authenticationInfo } = await verifyAuthenticationResponse({ ... });
if (verified && authenticationInfo) {
const { newCounter, credentialID } = authenticationInfo;
dbAuthenticator.counter = authenticationInfo.newCounter;
await updateCounterInDatabase({
credIDString: isoBase64URL.fromBuffer(credentialID),
newCounter,
});
}
After
// Registration
const { verified, registrationInfo } = await verifyRegistrationResponse({ ... });
if (verified && registrationInfo) {
const { credentialID } = registrationInfo;
await storeInDatabase({ credIDString: credentialID, ... });
}
// Authentication
const { verified, authenticationInfo } = await verifyAuthenticationResponse({ ... });
if (verified && authenticationInfo) {
const { newCounter, credentialID } = authenticationInfo;
dbAuthenticator.counter = authenticationInfo.newCounter;
await updateCounterInDatabase({ credIDString: credentialID, newCounter });
}