PHPackages                             wuxejian/filament-registration - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. wuxejian/filament-registration

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

wuxejian/filament-registration
==============================

Filament-native user registration with pluggable captcha (Cloudflare Turnstile, Google reCAPTCHA v3) and configurable default-role assignment.

1.2.0(3w ago)01↓100%MITPHPPHP ^8.2

Since May 19Pushed 3w agoCompare

[ Source](https://github.com/wuxuejian/filament-registration)[ Packagist](https://packagist.org/packages/wuxejian/filament-registration)[ Docs](https://github.com/tallcms/filament-registration)[ RSS](/packages/wuxejian-filament-registration/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (6)Versions (2)Used By (0)

Filament Registration
=====================

[](#filament-registration)

A Filament v5 plugin that wires up Filament-native user registration with pluggable captcha (Cloudflare Turnstile, Google reCAPTCHA v3) and configurable default-role assignment.

Filament has built-in `->registration()` support, but the default flow is just name/email/password — no captcha, no role assignment, no event bridge for hosts that listen on Laravel's `Registered` event. This plugin fills those gaps as a drop-in replacement that still uses Filament's documented hooks (no `register()` reimplementation, no internal copy-paste).

Features
--------

[](#features)

- **Filament-native register page** that extends `\Filament\Auth\Pages\Register`. Login ↔ register cross-linking works for free.
- **Pluggable captcha pipeline**: Cloudflare Turnstile, Google reCAPTCHA v3, or none. Settings managed through a Filament admin page; secrets are encrypted at rest.
- **Default-role assignment** with a graceful fallback: if the configured role doesn't exist, registration still succeeds and a warning is logged (so a misconfig doesn't lose all signups).
- **Honeypot field** + pre-captcha throttle protect the captcha vendor from amplification.
- **Laravel `Illuminate\Auth\Events\Registered` is fired** alongside Filament's own `Filament\Auth\Events\Registered` event, so listeners written for Laravel's event keep working.
- **Container-bound redirect response** so hosts can swap the post-registration redirect (e.g. send new users into an onboarding flow) without subclassing the page.

Installation
------------

[](#installation)

```
composer require tallcms/filament-registration
php artisan migrate
```

Add to your panel provider:

```
use Tallcms\FilamentRegistration\Filament\FilamentRegistrationPlugin;
use Tallcms\FilamentRegistration\Filament\Pages\Register;

public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->path('admin')
        ->login()
        ->registration(Register::class)            // explicit page class — required
        ->plugin(
            FilamentRegistrationPlugin::make()
                ->defaultRole('member')            // optional; null = no role assignment
        );
}
```

**Both `->registration(Register::class)` and `->plugin(FilamentRegistrationPlugin::make())` are required** and not interchangeable. `->registration()` with no argument uses Filament's default page; the captcha and role assignment only run when the explicit class is wired.

Optional: enable Filament's built-in email verification with `->emailVerification()`. The plugin defers to it — when the panel requires verification, Filament sends the verification email; when it doesn't, new users are pre-marked verified.

Configuration
-------------

[](#configuration)

Captcha settings come from two layers, with the higher one winning:

1. **Database** (managed via the Admin UI at **Settings → Registration**) — what the plugin shows in the form, with the secret encrypted at rest.
2. **Environment variables** — useful for keeping secrets out of source control and per-environment overrides (e.g. test keys in staging, real keys in prod).

The captcha provider is detected from whichever layer wins; you don't need to wire each provider individually.

### Environment variables

[](#environment-variables)

All optional. The plugin works fully through the Admin UI without any of these set.

VariableDefaultPurpose`FILAMENT_REGISTRATION_CAPTCHA_ENABLED`*unset* (auto)Force captcha on (`true`) or off (`false`). When unset, captcha auto-enables if both `SITE_KEY` and `SECRET_KEY` are present, and stays off otherwise.`FILAMENT_REGISTRATION_CAPTCHA_PROVIDER``turnstile``turnstile` (Cloudflare) or `recaptcha_v3` (Google).`FILAMENT_REGISTRATION_CAPTCHA_SITE_KEY``''`Public key embedded in the form. Safe to commit to source control if you want.`FILAMENT_REGISTRATION_CAPTCHA_SECRET_KEY``''`Private key for server-side verification. **Keep out of source control** — env or DB only.`FILAMENT_REGISTRATION_CAPTCHA_RECAPTCHA_MIN_SCORE``0.5`reCAPTCHA v3 only. Tokens scoring below this threshold are rejected. Range 0.0 (lenient) – 1.0 (strict).Example `.env` for production with Cloudflare Turnstile:

```
FILAMENT_REGISTRATION_CAPTCHA_ENABLED=true
FILAMENT_REGISTRATION_CAPTCHA_PROVIDER=turnstile
FILAMENT_REGISTRATION_CAPTCHA_SITE_KEY=0x4AAAAAAA...
FILAMENT_REGISTRATION_CAPTCHA_SECRET_KEY=0x4AAAAAAA...
```

The Admin UI's "Secret key status" indicator reads ✓ Configured when either layer (DB or env) supplies a secret. So if your secret lives in `.env`, you can leave the form's secret field blank — the form treats blank as "keep current".

### Authorization for the settings page

[](#authorization-for-the-settings-page)

By default the page is accessible to any user who can reach the panel (i.e. anyone who passes the panel's auth middleware). The plugin doesn't ship a built-in permission gate because Filament users have very different auth setups (some use Shield, some Bouncer, some plain canAccess(), some panel-level middleware). Pick whichever fits your app:

#### Using [TallCMS](https://tallcms.com) + Multisite plugin? (zero config)

[](#using-tallcms--multisite-plugin-zero-config)

If you're running [TallCMS](https://github.com/tallcms/tallcms) with the [Multisite plugin](https://github.com/tallcms/multisite-plugin) (the SaaS-style site-builder mode), install the [`tallcms/registration`](https://github.com/tallcms/user-registration-plugin) bridge plugin and you're done — the bridge gives you the full SaaS signup flow out of the box:

- Default role `site_owner` (with TallCMS's role-aware policy scoping so each new user only sees their own sites)
- Onboarding redirect into the Multisite Template Gallery for new users
- Default site-plan assignment so quotas apply from day one
- Themed login + register pages that match your active TallCMS theme
- 301 redirect from the legacy `/register` URL to the Filament-native page

```
# In a TallCMS + Multisite install
composer require tallcms/filament-registration
php artisan migrate
# Then upload the tallcms/registration bridge plugin via Admin → Plugins
```

No subclassing, no `canAccess()` override — TallCMS Multisite handles it. Read more at [tallcms.com](https://tallcms.com).

#### Using TallCMS without Multisite?

[](#using-tallcms-without-multisite)

The bridge plugin is mostly Multisite-coupled (its onboarding redirect and site-plan assignment both no-op without the Multisite plugin). For a vanilla TallCMS install, skip the bridge and use this plugin directly:

```
$panel
    ->registration(\Tallcms\FilamentRegistration\Filament\Pages\Register::class)
    ->plugin(
        FilamentRegistrationPlugin::make()
            ->defaultRole('author')   // or whichever role you want
    );
```

**On gating the settings page**: TallCMS's panel already requires authenticated admin access (`canAccessPanel()`), so unless you want a *stricter* gate (e.g. "only `super_admin` can edit captcha keys, not `editor` or `author`"), you don't need to add anything else. If you do want that stricter cut, see the [Shield subclass recipe below](#filament-shield-users) — note that Shield can't auto-discover this page (it's a vendor class without `HasPageShield`), so the subclass is the canonical wire-up; no `shield:generate` magic alternative exists.

#### Filament Shield users {#filament-shield-users}

[](#filament-shield-users-filament-shield-users)

Subclass the page and add the trait, then point your panel at the subclass:

```
namespace App\Filament\Pages;

use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Tallcms\FilamentRegistration\Filament\Pages\RegistrationSettings as BaseRegistrationSettings;

class RegistrationSettings extends BaseRegistrationSettings
{
    use HasPageShield;
}
```

Then run `php artisan shield:generate --page=RegistrationSettings --panel=` once and grant the resulting `View:RegistrationSettings` permission to roles via the Shield UI.

#### Plain `canAccess()` users

[](#plain-canaccess-users)

Subclass and override:

```
public static function canAccess(): bool
{
    return auth()->user()?->is_admin ?? false;
}
```

**Optional dependency note**: role assignment via `defaultRole(...)` requires `spatie/laravel-permission` (suggested in `composer.json`). Hosts without Spatie permissions get role assignment as a no-op — no fatal error, the user is still created.

Customising the post-register redirect
--------------------------------------

[](#customising-the-post-register-redirect)

Bind a custom response in your service provider:

```
use Filament\Auth\Http\Responses\Contracts\RegistrationResponse;
use App\Http\Responses\OnboardingRegistrationResponse;

public function register(): void
{
    $this->app->bind(RegistrationResponse::class, OnboardingRegistrationResponse::class);
}
```

Your concrete just needs to implement `RegistrationResponse` (which extends `Responsable`) and return a `RedirectResponse` from `toResponse()`.

Behaviour notes
---------------

[](#behaviour-notes)

- **Honeypot**: a non-empty honeypot field returns a validation error, not a fake-success page. Bots see the form bounce; humans never trigger it.
- **Throttling**: pre-captcha throttle is 30 attempts per IP per minute (protects the captcha vendor). Filament's built-in throttle (2 attempts per minute, 2 per email per minute) covers the post-validation case.
- **Email verification**: defers to Filament's `->emailVerification()` panel method. No custom verification view is shipped.

Compatibility
-------------

[](#compatibility)

- PHP 8.2+
- Filament v5+
- spatie/laravel-permission v6+ (for role assignment)

License
-------

[](#license)

MIT.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance95

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 85.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

22d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4558715?v=4)[wuxuejian](/maintainers/wuxuejian)[@wuxuejian](https://github.com/wuxuejian)

---

Top Contributors

[![tallcms](https://avatars.githubusercontent.com/u/253660574?v=4)](https://github.com/tallcms "tallcms (12 commits)")[![wuxuejian](https://avatars.githubusercontent.com/u/4558715?v=4)](https://github.com/wuxuejian "wuxuejian (2 commits)")

---

Tags

authrecaptchacaptcharegistrationfilamentfilament-pluginturnstile

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/wuxejian-filament-registration/health.svg)

```
[![Health](https://phpackages.com/badges/wuxejian-filament-registration/health.svg)](https://phpackages.com/packages/wuxejian-filament-registration)
```

###  Alternatives

[anhskohbo/no-captcha

No CAPTCHA reCAPTCHA For Laravel.

1.8k8.8M34](/packages/anhskohbo-no-captcha)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k3.5M115](/packages/bezhansalleh-filament-shield)[josiasmontag/laravel-recaptchav3

Recaptcha V3 for Laravel package

2691.8M2](/packages/josiasmontag-laravel-recaptchav3)[buzz/laravel-google-captcha

Google captcha for Laravel

2111.1M2](/packages/buzz-laravel-google-captcha)[andrewdwallo/filament-companies

A comprehensive Laravel authentication and authorization system designed for Filament, focusing on multi-tenant company management.

34654.9k2](/packages/andrewdwallo-filament-companies)[stephenjude/filament-two-factor-authentication

Filament Two Factor Authentication: Google 2FA + Passkey Authentication

84192.9k7](/packages/stephenjude-filament-two-factor-authentication)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
