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

Mfakitv4 Laravel Package

jeffersongoncalves/mfakitv4

MFA Kit for Filament v4 adds multi-factor authentication to Laravel admin panels, with TOTP setup, QR code enrollment, recovery codes, and easy user profile integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Because this is a starter kit rather than a drop-in library, "installing" it means scaffolding a project from it, not composer require-ing it into an existing app. Create a fresh Laravel 13.x app, then pull the MFAKit skeleton over the top (clone/copy the repo, or use it as a GitHub template), then:

cp .env.example .env
composer install
php artisan key:generate

# MFA driver config — set these before first boot
# MAIL_* for the email channel
# WHATSAPP_* / Twilio-style credentials for the WhatsApp channel

php artisan migrate --seed
php artisan serve

Where to look first, in order:

  1. The MFA config file (config/mfakit.php or similar) — this is the single most important file. It defines which factors are enabled, OTP lengths, TTLs, recovery-code behaviour, and the WhatsApp provider. Read this before touching anything else.
  2. The Filament panel provider (app/Providers/Filament/*PanelProvider.php) — where the MFA challenge pages and the user "Security" page get registered.
  3. The User model + migration — look for the columns holding the TOTP secret, confirmed-at timestamp, channel preference, and recovery codes. These tell you the intended data model faster than any doc.
  4. The middleware stack — the kit almost certainly ships an EnsureMfaIsVerified-style middleware. Find where it's aliased and where it's applied.

First use case worth proving end-to-end: log in as the seeded user, go to the profile/security page, enrol a TOTP factor by scanning the QR with an authenticator app, confirm the 6-digit code, log out, and log back in to hit the challenge screen. Getting that loop working validates config, migrations, Filament auth wiring, and QR generation in one pass. Add email/WhatsApp only after TOTP works.

Implementation Patterns

Factor enrolment as a Filament page action. The idiomatic pattern in a Filament 4 kit is a "Security" page on the user's own profile with three sections (TOTP / Email / WhatsApp), each with an enable action. Enrolment is two-phase everywhere: generate a secret → show QR or send a code → user submits a code → flip confirmed_at. Never treat "secret generated" as "factor active"; users abandon enrolment halfway and you'll lock them out.

Challenge state lives in the session, not the user row. After primary auth succeeds, the middleware should stash mfa.verified_at (or a similar marker) in the session and redirect to the challenge page. This keeps "logged in but not yet MFA-verified" as an explicit intermediate state. If you find the kit instead writing a flag onto the user or logging them fully in and gating per-request, be deliberate about which you keep — the session approach survives browser restarts and is easier to reason about.

Gate the panel, not just the routes. In Filament 4, apply the MFA middleware in the panel's middleware() array so Filament's own pages, Livewire endpoints, and auth screens are all covered. Registering it only in web or bootstrap/app.php global stack is the classic mistake — Filament's Livewire requests take a different path and can slip through.

One channel, one service class. For the email and WhatsApp factors, extract a SendOtp contract with EmailOtpSender and WhatsAppOtpSender implementations bound in a service provider. This is the extension point you'll actually use: swapping WhatsApp providers, adding SMS, or routing through a notification class. It also makes the factor testable without hitting a gateway.

Recovery codes as a first-class factor. Generate a batch (typically 8–10) on first MFA activation, hash them at rest, show them exactly once, and consume-and-delete on use. Expose a "regenerate recovery codes" action behind a password confirmation. If the kit ships recovery codes in plaintext, change that before production.

Enforcement policy belongs in config, not middleware. A common real-world need is "admins must have MFA, customers may opt in." Rather than forking the middleware, drive it from config or a requiresMfa() method on the User model, and let the middleware consult that. Then scoping enforcement per-panel or per-role becomes a config change.

Testing pattern. Freeze time for TOTP windows, and assert both the happy path and the "code already used" path — most implementations forget replay protection within the same 30-second window. For WhatsApp, bind a fake sender in the container so tests never touch the network.

Gotchas and Tips

  • TOTP clock drift. Validate with a ±1 window rather than exactly 30 seconds; real phones drift. But also store the last accepted timestep per user and reject reuse inside the window, or a leaked code is replayable.
  • WhatsApp is not free and not instant. Delivery is async and can fail silently. Treat the send as fire-and-forget with a queue, add a "resend code" cooldown (30–60s) and a hard attempt cap, and give users a fallback factor. A WhatsApp-only account with a dead number is a support ticket.
  • Rate-limit the challenge route. The MFA page is an unauthenticated-by-design endpoint — six digits is only a million combinations. Apply throttle: middleware plus per-user attempt counters that lock the account after N failures.
  • Filament auth guard mismatch. If you have multiple panels, the challenge middleware must resolve the correct guard. Read the guard from the current panel (Filament::getCurrentPanel()->getAuthGuard()) rather than hardcoding web, or a second panel will authenticate against the wrong session key.
  • config:cache will bite you. Enabling/disabling factors at runtime by mutating config won't survive php artisan config:cache. If admins can toggle factors from the UI, persist those settings in the database and layer them over the config file.
  • Email OTP expiry vs. mail latency. A 2-minute TTL is common but cruel with greylisted mail servers. 5–10 minutes with single-use enforcement is kinder; log the issue time so support can diagnose "the code expired" complaints.
  • Migrations assume a fresh DB. As a starter kit, expect non-idempotent migrations and a seed that assumes empty tables. If you're grafting it into an existing app, extract just the MFA columns into your own migration rather than running the kit's.
  • Debugging the challenge loop. If you're bounced between login and challenge, dump the session keys after primary auth and confirm the middleware ordering — Authenticate must run before the MFA check, and the challenge route itself must be in the middleware's exclusion list or you get a redirect loop.
  • Ten stars means read the source. This is a low-traffic, recent package. There's no Stack Overflow corpus behind it. Budget an afternoon to read the middleware, the enrolment actions, and the config file end-to-end before building on it, and pin the commit you copied from — there's no guarantee of a stable upgrade path.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource