Weave 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

Two Factor Authentication Livewire Laravel Package

liberusoftware/two-factor-authentication-livewire

A Laravel Livewire package for adding two-factor authentication to your app. It provides components for enabling 2FA, verifying authentication codes, and managing recovery codes, helping secure user accounts with a straightforward setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a presentation adapter: it ships Livewire components that wrap an underlying two-factor authentication service (Fortify-style or a liberusoftware/module-two-factor-authentication core). Treat it as the UI layer — the enable/disable/verify logic lives elsewhere. That distinction shapes everything below.

Minimal steps:

  1. Require the package and its core dependency:
    composer require liberusoftware/two-factor-authentication-livewire
    
  2. Publish config and Livewire views (check php artisan vendor:publish --provider="LiberuSoftware\TwoFactorAuthenticationLivewire\TwoFactorAuthenticationServiceProvider" — namespace may differ; run vendor:publish interactively to confirm tags).
  3. Ensure users implement the expected contract (e.g. TwoFactorAuthenticatable) and that the two_factor_* columns/migration exist — usually supplied by the core module, not this one.
  4. Drop the challenge component into your auth flow. Typical first use case: a /user/two-factor-authentication settings page rendering the enable component, and a middleware-protected challenge component rendered after password login for users with 2FA confirmed.

First thing to verify: read src/Livewire/ and routes/ — that tells you exactly which component aliases (<livewire:two-factor-authentication.enable /> etc.) and routes (typically /user/two-factor-qr-code, /user/two-factor-recovery-codes, /user/confirm-password) are registered. These are almost always Fortify-compatible endpoint names.

Implementation Patterns

Settings page (enable/disable + recovery codes). Render the enable component conditionally on $user->two_factor_secret:

@if ($user->two_factor_secret && ! $user->two_factor_confirmed_at)
    <livewire:two-factor-authentication.confirm />
@elseif ($user->two_factor_confirmed_at)
    <livewire:two-factor-authentication.recovery-codes />
    <livewire:two-factor-authentication.disable />
@else
    <livewire:two-factor-authentication.enable />
@endif

Login challenge. After Auth::attempt(), redirect users with a confirmed secret to a challenge route rather than the dashboard:

if ($user->two_factor_confirmed_at) {
    session(['2fa.user_id' => $user->id]);
    return redirect()->route('two-factor.challenge');
}

The challenge component reads the pending user from session, verifies the TOTP or recovery code via the core module, then calls Auth::loginUsingId() and session()->forget('2fa.user_id').

Recovery code rotation. Recovery codes are typically regenerated via a POST to /user/two-factor-recovery-codes — wire a wire:click button to that endpoint (usually with wire:confirm to prevent accidental regeneration, since it invalidates old codes).

Disable gating. Pair the disable component with password.confirm middleware — 2FA should never be turned off from a hijacked session without re-entering the password.

Composition with Breeze/Jetstream. These packages assume Fortify's underlying routes. If you're not using Fortify, either install it alongside so the endpoints exist, or stub the three JSON endpoints (qr-code, recovery-codes GET/POST, secret-key) in your own controller — the Livewire components just fetch() them.

Gotchas and Tips

  • Two packages, one system. The common failure mode is installing this UI adapter without the core two-factor-authentication module (or Fortify). Components render but TwoFactorAuthentication::enable() calls explode with "class not found" or a 419/404 on the fetch endpoints. Always confirm the core is present and its migration has run.
  • two_factor_confirmed_at vs two_factor_secret. Enable state, confirmation state, and "has recovery codes" are three separate flags. Rendering the wrong component for a half-enabled user (secret set, not confirmed) leaves them in limbo — they can't log in and can't regenerate codes. Handle the unconfirmed branch explicitly.
  • Session key assumptions. The challenge component likely reads a specific session key (often 2fa.user_id or login.id). If you use a custom login flow, mirror that key or override the component — the package won't tell you which key it wants until you read the source.
  • Livewire fetch calls and CSRF. QR-code and recovery-code endpoints are JSON routes protected by auth + CSRF. If you mount the enable component outside the authenticated area (e.g. during registration), those fetches return 401/419 silently — check the browser network tab before debugging the component.
  • QR code regeneration. two_factor_secret is only populated on first enable; hitting "enable" twice without the disable step can rotate the secret underneath an already-scanned QR, locking users out. Guard the enable action on the server.
  • Recovery codes are shown once. The recovery-codes component typically re-fetches from the server every render, meaning codes are visible in the DOM to anyone with the session. Do not cache or Livewire-snapshot the codes — the core module usually stores them encrypted and returns plaintext only on demand.
  • Extension points live in the core. If you need custom policy (e.g. "2FA required for admins only"), don't subclass the Livewire components — subclass the core service or add a middleware + a must_enable flag on the user model. The adapter is thin by design.
  • Low-maturity package. Zero stars and NOASSERTION license means: pin the version in composer.json, vendor the components into your app if you need to patch them, and expect namespace/route drift between minor versions. Write a smoke test (enable → confirm → login → recover → disable) so upgrades fail loudly rather than at the login screen.
  • Debugging tip. Livewire's devtools/wire:model errors on the challenge form usually trace back to the core module's exception on an expired TOTP window — surface those as validation errors, not 500s, or users will see blank screens on stale codes.
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel