Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Webauthn Symfony Bundle Laravel Package

web-auth/webauthn-symfony-bundle

Symfony bundle integrating WebAuthn (passkeys/FIDO2) for strong, passwordless authentication. Provides registration and login flows, configuration, and helpers to add secure WebAuthn support to Symfony apps with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require web-auth/webauthn-symfony-bundle
    

    Add the bundle to config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    WebAuthn\Bundle\WebauthnBundle::class => ['all' => true],
    
  2. Configuration Copy and configure .env variables (or config/webauthn.php):

    WEB_AUTHN_RP_ID=https://yourdomain.com
    WEB_AUTHN_RP_NAME="Your App Name"
    WEB_AUTHN_RP_ORIGIN=https://yourdomain.com
    WEB_AUTHN_ATTESTATION=direct
    WEB_AUTHN_USER_VERIFICATION=preferred
    
  3. First Use Case: Registration

    use WebAuthn\Bundle\WebauthnBundle\Service\WebAuthnService;
    
    // In your controller:
    $webauthn = $this->get('webauthn');
    $user = $this->getUser(); // Your authenticated user
    
    // Generate registration options
    $options = $webauthn->getRegistrationOptions($user);
    return new JsonResponse($options);
    
    // Handle verification
    $result = $webauthn->verifyRegistrationResponse($user, $data);
    

Implementation Patterns

Workflow: Registration Flow

  1. Generate Options

    $options = $webauthn->getRegistrationOptions($user);
    
    • Returns PublicKeyCredentialCreationOptions (JSON-serializable).
    • Include in frontend template (e.g., <input type="hidden" id="challenge" value="...">).
  2. Frontend Integration Use the WebAuthn API to collect credentials:

    navigator.credentials.create({ publicKey: options });
    
  3. Verify Response

    $result = $webauthn->verifyRegistrationResponse($user, $data);
    if ($result->isSuccess()) {
        $user->webauthnCredentials()->create([
            'id' => $result->getCredentialId(),
            'public_key' => $result->getPublicKey(),
            'sign_count' => $result->getSignCount(),
            'transports' => $result->getTransports(),
        ]);
    }
    

Workflow: Authentication Flow

  1. Generate Assertion Options

    $options = $webauthn->getAuthenticationOptions($user);
    
  2. Frontend Assertion

    navigator.credentials.get({ publicKey: options });
    
  3. Verify Assertion

    $result = $webauthn->verifyAuthenticationResponse($user, $data);
    if ($result->isSuccess()) {
        // Update sign count
        $credential = $user->webauthnCredentials->find($result->getCredentialId());
        $credential->update(['sign_count' => $result->getSignCount()]);
    }
    

Integration Tips

  • Database Schema: Use migrations to add webauthn_credentials table (see schema).
  • Middleware: Protect routes with webauthn.login_required or custom middleware.
  • Fallback: Combine with password auth (e.g., Auth::attempt() if WebAuthn fails).
  • Laravel-Specific: Use Symfony\Component\HttpFoundation\Request via $request->getContent() for raw POST data.

Gotchas and Tips

Pitfalls

  1. RP ID Mismatch

    • Ensure WEB_AUTHN_RP_ID matches your domain exactly (no subdomains unless configured).
    • Debug with: dd($webauthn->getRelyingParty()->getId());.
  2. User Verification

    • WEB_AUTHN_USER_VERIFICATION=required forces biometric/pin auth. Test with preferred first.
  3. Attestation

    • direct (default) requires HTTPS. Use none for testing (insecure).
  4. Credential Storage

    • Store credential_id as binary (LONGRAW in MySQL) or hex string. Avoid base64 URL-safe encoding in DB.
  5. Sign Count

    • Always update sign_count on successful authentication to prevent replay attacks.

Debugging

  • Enable Logging
    # config/packages/webauthn.yaml
    webauthn:
        debug: true
    
  • Raw Responses Dump $data (from frontend) to verify structure:
    dd(json_decode($request->getContent(), true));
    
    Expected keys: id, rawId, type, response (with authenticatorData, clientDataJSON, signature, etc.).

Extension Points

  1. Custom Credential Storage Override WebAuthn\Bundle\WebAuthnBundle\Repository\CredentialRepositoryInterface for non-DB storage (e.g., Redis).

  2. Event Listeners Subscribe to webauthn.registration.success or webauthn.authentication.success:

    // config/packages/webauthn.yaml
    webauthn:
        listeners:
            registration_success: App\EventListener\WebAuthnRegistrationListener
    
  3. Frontend Adaptors Use libraries like @simplewebauthn/browser for React/Vue integration.

  4. Multi-Factor Combine with Laravel’s auth:attempt for password + WebAuthn:

    if ($webauthn->verifyAuthenticationResponse($user, $data)->isSuccess()) {
        Auth::login($user, true);
    }
    

Pro Tips

  • Testing: Use tools like webauthn-test or mock responses in PHPUnit.
  • Performance: Cache getRegistrationOptions() if user/device hasn’t changed.
  • Security: Sanitize rp_id to prevent open redirects (e.g., filter_var($rpId, FILTER_VALIDATE_URL)).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope