Protecting Your Laravel Site from Spam Signups with Jetstream and Spatie Honeypot

Bill Richards October 1, 2024

When it comes to building a modern Laravel application, Jetstream makes setting up user authentication a breeze. However, with the ease of user registration, we often face another challenge: spam bots attempting to abuse sign-up forms.

To tackle this issue, I’ll show you how to customize Laravel Jetstream and Fortify to prevent spam abuse, using a simple and effective technique: adding Spatie's Honeypot package. Honeypot adds an invisible field to your forms that, when filled out by bots, flags the submission as spam. It's an elegant solution that’s easy to integrate with Jetstream.

In this post, I’ll guide you through the process of:

  1. Installing and configuring Spatie's Honeypot package.
  2. Customizing Jetstream's usage of Laravel Fortify.
  3. Adding middleware to protect your registration form from bots.

Let’s dive in!

Step 1: Installing Spatie Honeypot

First things first, we need to install the Honeypot package. You can do this using composer:

composer require spatie/laravel-honeypot

Once installed, publish the configuration file:

php artisan vendor:publish --provider="Spatie\Honeypot\HoneypotServiceProvider"

This will create a honeypot.php config file where you can tweak settings such as the field name or timing threshold, but the defaults are usually sufficient for most use cases.

Step 2: Integrating Honeypot with Jetstream's Registration

Jetstream uses Laravel Fortify under the hood for user authentication, so to customize the registration process, we'll need to tap into Fortify’s pipeline and make some adjustments. Under config/fortify.php we'll need to comment out the registration defaults so we can customize it manually. Your feature section will look like this.

    'features' => [
        // Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        Features::twoFactorAuthentication([
            'confirm' => true,
            'confirmPassword' => true,
            // 'window' => 0,
        ]),
    ],

Next, we'll modify FortifyServiceProvider.php to manually configure out registrations route so we can utilize the honeypot middleware.

class FortifyServiceProvider extends ServiceProvider
{
        /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // default code here...

        $this->configureRoutes(); //newly added
    }

        /**
     * Configure the routes offered by the application.
     *
     * @return void
     */
    protected function configureRoutes()
    {
        Route::group([
            'domain' => config('fortify.domain', null),
            'prefix' => config('fortify.prefix'),
            'middleware' => config('fortify.middleware', ['web']),
        ], function () {
            // Manually define registration routes with honeypot middleware
            Route::get(RoutePath::for('register', '/register'), [RegisteredUserController::class, 'create'])
                ->middleware(['guest:' . config('fortify.guard'), ProtectAgainstSpam::class])
                ->name('register');

            Route::post(RoutePath::for('register', '/register'), [RegisteredUserController::class, 'store'])
                ->middleware(['guest:' . config('fortify.guard'), ProtectAgainstSpam::class]);
        });
    }
}

Don't forget to import the classes. That's really all there is to it! Your registration routes are now protected by the honeypot middleware. We have one final step to complete this update.

Step 3: Updating the Registration Form

Next, we'll update the registration form that Jetstream provides to include the honeypot fields. Spatie makes this super easy by using their Blade directive to insert the honeypot fields directly into the form.

In your registration Blade view, typically located at resources/views/auth/register.blade.php, add the following line inside your form:

<x-honeypot />

This will automatically add the invisible honeypot field to the form. The Honeypot package will then handle detecting and rejecting bot submissions behind the scenes.

Conclusion

By combining Jetstream’s powerful authentication system with Spatie’s Honeypot package, you can drastically reduce the number of spam signups on your Laravel application. It’s a lightweight and simple solution that helps protect your site without adding unnecessary friction for legitimate users.

With this approach in place, your registration process will be much more resilient to abuse, allowing you to focus on building and scaling your application.

Cheers,
Bill