@web-auth/webauthn-stimulus
v5.3.2
Published
Webauthn integration for Symfony
Maintainers
Readme
@web-auth/webauthn-stimulus
WebAuthn Stimulus controllers for passwordless authentication in web applications.
This package provides ready-to-use Stimulus controllers for implementing WebAuthn/FIDO2 authentication (passkeys) in your web applications. It wraps @simplewebauthn/browser to provide an easy-to-use interface for credential registration and authentication.
Features
- 🔐 Passwordless authentication with WebAuthn/FIDO2
- 🔑 Passkey support (biometrics, security keys, platform authenticators)
- 🎯 Three specialized controllers: authentication, registration, and legacy combined
- 🌐 Browser autofill support (conditional UI)
- 📱 Platform authenticator detection (Face ID, Touch ID, Windows Hello)
- ⚡ Event-driven architecture for custom integrations
- 🎨 Framework agnostic (works with any Stimulus-enabled app)
Installation
npm install @web-auth/webauthn-stimulusDependencies
This package requires:
@hotwired/stimulus^3.0.0@simplewebauthn/browser^13.2.0
These are listed as peer dependencies and should be installed in your project.
Usage with Module Bundlers
With any module bundler (webpack, Vite, esbuild…), import controllers from the package entry point and register them yourself:
import { Application } from '@hotwired/stimulus';
import { AuthenticationController, RegistrationController } from '@web-auth/webauthn-stimulus';
const app = Application.start();
app.register('webauthn--authentication', AuthenticationController);
app.register('webauthn--registration', RegistrationController);Available Controllers
1. Authentication Controller (authentication-controller.js)
Handles user sign-in with existing credentials.
<form
data-controller="webauthn--authentication"
data-webauthn--authentication-options-url-value="/auth/options"
data-webauthn--authentication-result-url-value="/auth/verify"
data-webauthn--authentication-conditional-ui-value="true"
data-action="submit->webauthn--authentication#authenticate">
<input
type="text"
name="username"
autocomplete="username webauthn"
data-webauthn--authentication-target="username" />
<input type="hidden" data-webauthn--authentication-target="result" />
<button type="submit">Sign In</button>
</form>Features:
- Browser autofill support (conditional UI)
- Platform authenticator availability detection
- Flexible result handling (API or form submission)
- Optional redirect after success
2. Registration Controller (registration-controller.js)
Handles new credential registration (user sign-up).
<form
data-controller="webauthn--registration"
data-webauthn--registration-options-url-value="/register/options"
data-webauthn--registration-result-url-value="/register/verify"
data-action="submit->webauthn--registration#register">
<input type="text" name="username" data-webauthn--registration-target="username" />
<input type="text" name="displayName" data-webauthn--registration-target="displayName" />
<select name="attestation" data-webauthn--registration-target="attestation">
<option value="none">None</option>
<option value="direct">Direct</option>
</select>
<input type="hidden" data-webauthn--registration-target="result" />
<button type="submit">Register</button>
</form>Features:
- Configurable attestation level
- Resident key support
- User verification options
- Authenticator attachment preferences
- Auto-register mode (conditional create)
3. Legacy Controller (controller.js)
Combined controller for backward compatibility. Handles both registration and authentication.
<form data-controller="webauthn">
<!-- Registration -->
<button data-action="webauthn#signup">Sign Up</button>
<!-- Authentication -->
<button data-action="webauthn#signin">Sign In</button>
</form>Deprecated since 5.3.x: importing this controller as
@web-auth/webauthn-stimulus/webauthnis deprecated and will be removed in 6.0. Use the canonical name@web-auth/webauthn-stimulusand pull theWebauthnControllernamed export instead:import { WebauthnController } from '@web-auth/webauthn-stimulus';
Configuration Values
Common Values (all controllers)
| Value | Type | Description | Default |
| -------------------- | ------- | ------------------------------ | -------- |
| optionsUrl | String | URL to fetch options from | Required |
| resultUrl | String | URL to send result to | Required |
| submitViaForm | Boolean | Submit via form instead of API | false |
| successRedirectUri | String | Redirect URL after success | - |
Authentication-specific Values
| Value | Type | Description | Default |
| --------------------- | ------- | ---------------------------- | ------- |
| conditionalUi | Boolean | Enable browser autofill | false |
| verifyAutofillInput | Boolean | Verify autofill input exists | true |
Registration-specific Values
| Value | Type | Description | Default |
| -------------- | ------- | ------------------------- | ------- |
| autoRegister | Boolean | Enable auto-register mode | false |
Events
All controllers dispatch custom events for integration:
Success Events
webauthn:connect- Controller connectedwebauthn:options:request- Options requestedwebauthn:options:success- Options receivedwebauthn:authenticator:response- Authenticator respondedwebauthn:attestation:success- Registration successfulwebauthn:assertion:success- Authentication successful
Error Events
webauthn:unsupported- WebAuthn not supportedwebauthn:options:failure- Failed to get optionswebauthn:attestation:failure- Registration failedwebauthn:assertion:failure- Authentication failed
Event Handling Example
document.addEventListener('webauthn:assertion:success', (event) => {
console.log('Authentication successful!', event.detail);
});
document.addEventListener('webauthn:assertion:failure', (event) => {
console.error('Authentication failed:', event.detail.exception);
});Server-Side Integration
Your backend needs to provide two endpoints per operation:
For Authentication
- Options endpoint (
GET/POST) - ReturnsPublicKeyCredentialRequestOptions - Verification endpoint (
POST) - Verifies the authentication response
For Registration
- Options endpoint (
GET/POST) - ReturnsPublicKeyCredentialCreationOptions - Verification endpoint (
POST) - Verifies and stores the credential
See @simplewebauthn/server for server-side implementation examples.
Symfony Integration
The recommended path for Symfony applications is to install this npm package straight from your asset pipeline. The package ships a symfony.importmap configuration so Symfony AssetMapper resolves the canonical sub-paths (/authentication, /registration, /webauthn) out of the box.
With Symfony AssetMapper (recommended)
php bin/console importmap:require @web-auth/webauthn-stimulusThen enable the controllers you want in assets/controllers.json:
{
"controllers": {
"@web-auth/webauthn-stimulus": {
"authentication": { "enabled": true, "fetch": "eager" },
"registration": { "enabled": true, "fetch": "eager" }
}
}
}You can now use the stimulus_controller() Twig helper:
<form {{ stimulus_controller('@web-auth/webauthn-stimulus/authentication') }}>
{# ... #}
</form>With Webpack Encore / Vite / any other bundler
Install the package and register the controllers yourself — see Usage with Module Bundlers above.
Deprecated: the web-auth/webauthn-stimulus Composer package
Deprecated since 5.3.x — removed in 6.0.0. The PHP wrapper
web-auth/webauthn-stimulusis no longer needed: this npm package is the canonical and only maintained source going forward. New projects should not install it; existing projects should migrate toimportmap:require(ornpm install) before upgrading to 6.0.0.
For more context and migration steps, see the project documentation.
Browser Support
Requires browsers with WebAuthn support:
- Chrome/Edge 67+
- Firefox 60+
- Safari 13+
- Opera 54+
Check support at runtime:
import { browserSupportsWebAuthn } from '@simplewebauthn/browser';
if (browserSupportsWebAuthn()) {
// Show WebAuthn UI
}Examples
With API Verification
<form
data-controller="webauthn--authentication"
data-webauthn--authentication-options-url-value="/api/auth/options"
data-webauthn--authentication-result-url-value="/api/auth/verify"
data-webauthn--authentication-success-redirect-uri-value="/dashboard">
<!-- Form fields -->
</form>With Form Submission
<form
data-controller="webauthn--registration"
data-webauthn--registration-options-url-value="/register/options"
data-webauthn--registration-submit-via-form-value="true">
<input type="hidden" data-webauthn--registration-target="result" />
<!-- Form fields -->
</form>With Browser Autofill
<form data-controller="webauthn--authentication" data-webauthn--authentication-conditional-ui-value="true">
<input
type="text"
name="username"
autocomplete="username webauthn"
data-webauthn--authentication-target="username" />
</form>Development
# Install dependencies
npm install
# Run tests
npm test
# Lint code
npm run lint
# Format code
npm run formatResources
- WebAuthn Guide - Introduction to WebAuthn
- SimpleWebAuthn Documentation - Library documentation
- Passkeys.dev - Passkey resources
- FIDO Alliance - WebAuthn standards
License
MIT - See LICENSE file for details.
Contributing
This is a sub-package of the web-auth/webauthn-framework monorepo.
Please submit issues and pull requests to the main repository:
- Issues: https://github.com/web-auth/webauthn-framework/issues
- Pull Requests: https://github.com/web-auth/webauthn-framework/pulls
Credits
- Author: Florent Morselli
- Contributors: All contributors
