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 Stimulus Laravel Package

web-auth/webauthn-stimulus

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require web-auth/webauthn-stimulus
    

    Ensure your project uses Symfony 5.4+ and PHP 8.0+.

  2. Enable the Bundle Add to config/bundles.php:

    return [
        // ...
        WebAuth\UX\WebauthnBundle::class => ['all' => true],
    ];
    
  3. Configure the Bundle Update config/packages/webauthn.yaml (auto-generated):

    webauthn:
        rp_name: "YourAppName"
        rp_id: "yourdomain.com"  # Must match your domain
        signature_algorithm: -7  # ES256 (recommended)
        attestation_conveyance_preference: "none"
        user_verification: "preferred"
    
  4. First Use Case: Registration

    • Generate a registration challenge in a controller:
      use WebAuth\UX\WebauthnBundle\Webauthn\Webauthn;
      
      public function register(Webauthn $webauthn): Response
      {
          $challenge = $webauthn->createRegistrationChallenge();
          return $this->render('registration.html.twig', [
              'challenge' => $challenge->getChallenge(),
              'options' => $challenge->getOptions(),
          ]);
      }
      
    • Use the Stimulus controller (webauthn_controller.js) to handle client-side Webauthn flow.

Implementation Patterns

Workflow: Registration Flow

  1. Server-Side (Symfony)

    • Generate a registration challenge (createRegistrationChallenge()).
    • Pass challenge data to the frontend (e.g., via Twig).
    • After user completes registration, verify the response:
      $result = $webauthn->verifyRegistrationResponse(
          $userId,  // User identifier (e.g., UUID)
          $username,
          $responseData,
          $challenge->getChallenge()
      );
      
  2. Client-Side (Stimulus)

    • Use webauthn_controller.js to trigger the Webauthn API:
      this.webauthn.register({
          challenge: this.data.get('challenge'),
          options: this.data.get('options'),
          success: (response) => {
              this.dispatch('webauthn:registered', { detail: response });
          },
      });
      
    • Handle the webauthn:registered event in your app to submit the response to the server.
  3. Integration with Forms

    • For Symfony forms, use the WebauthnType:
      $builder->add('webauthn', WebauthnType::class, [
          'webauthn' => $webauthn,
          'user_id' => $user->getId(),
          'username' => $user->getEmail(),
      ]);
      

Workflow: Authentication Flow

  1. Generate a Login Challenge
    $challenge = $webauthn->createAuthenticationChallenge($userId);
    
  2. Client-Side Authentication
    this.webauthn.authenticate({
        challenge: this.data.get('challenge'),
        allowCredentials: this.data.get('allowCredentials'),
        success: (response) => {
            this.dispatch('webauthn:authenticated', { detail: response });
        },
    });
    
  3. Verify the Response
    $result = $webauthn->verifyAuthenticationResponse(
        $userId,
        $responseData,
        $challenge->getChallenge()
    );
    

Integration Tips

  • User Verification: Set user_verification: "required" in config if you need explicit user presence (e.g., PIN entry).
  • Attestation: Use attestation_conveyance_preference: "direct" for self-service registrations or "none" for privacy.
  • Fallbacks: Combine with password auth for broader compatibility:
    {% if webauthn_supported %}
        {# Webauthn registration form #}
    {% else %}
        {# Fallback to password form #}
    {% endif %}
    
  • Testing: Use the webauthn:mock service in tests:
    $this->container->get('webauthn')->setMockMode(true);
    

Gotchas and Tips

Pitfalls

  1. RP ID Mismatch

    • The rp_id in config must match the domain where Webauthn is used (e.g., https://app.example.com).
    • Fix: Use webauthn:rp-id command to validate:
      php bin/console webauthn:rp-id
      
  2. Challenge Timing

    • Challenges expire after ~30 seconds. Ensure client-side requests are fast or handle failures gracefully.
    • Tip: Use AbortController in Stimulus to cancel pending requests if the page unloads.
  3. Credential Storage

    • Stored credentials are tied to the user_id and username. Changing either may break authentication.
    • Workaround: Migrate credentials if user data changes (e.g., during username updates).
  4. Browser Support

    • Webauthn requires HTTPS and modern browsers (Chrome, Firefox, Edge, Safari 13+).
    • Fallback: Detect support with:
      if (!window.PublicKeyCredential) {
          // Show fallback UI
      }
      
  5. Debugging Failures

    • Enable debug mode in webauthn.yaml:
      debug: true
      
    • Check logs for errors like:
      • Invalid challenge (timing issue).
      • Credential already exists (duplicate registration).
      • User verification required (config mismatch).

Tips

  1. Customize Authenticator Options Extend the default options in your controller:

    $options = $webauthn->createRegistrationOptions();
    $options->setAuthenticatorAttachment('platform'); // or 'cross-platform'
    $options->setRequireResidentKey(true);
    
  2. Handle Multiple Credentials For users with multiple devices, store credentials in a credentials JSON column:

    $credentials = json_decode($user->getCredentials(), true) ?: [];
    $credentials[] = $result->getCredential();
    $user->setCredentials(json_encode($credentials));
    
  3. Security Headers Ensure your server sends:

    Content-Security-Policy: frame-ancestors 'self'
    

    To prevent clickjacking attacks on Webauthn prompts.

  4. Extension Points

    • Custom Verifiers: Implement WebAuth\UX\WebauthnBundle\Webauthn\Verifier\VerifierInterface for custom logic.
    • Event Listeners: Subscribe to webauthn.registration.success or webauthn.authentication.success events.
  5. Performance

    • Pre-generate challenges in background jobs if registration/auth is slow.
    • Cache allowCredentials for authentication flows to reduce payload size.
  6. Local Development Use ngrok to expose your local dev server with a valid domain:

    ngrok http 8000
    

    Update rp_id to your ngrok subdomain (e.g., your-subdomain.ngrok.io).

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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor