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

Authentication Guard Bundle Laravel Package

metaclass-nl/authentication-guard-bundle

Symfony bundle for integrating guard-based authentication into your application. It helps wire custom authentication guards into Symfony Security so you can protect routes and control how users are authenticated, with straightforward configuration and reusable guard support.

View on GitHub
Deep Wiki
Context7

Getting Started

First reality check: metaclass-nl/authentication-guard-bundle is a Symfony 2 bundle, not a Laravel package. It will not drop into a Laravel app, and there is no Laravel equivalent release. It also has no releases since 2017 and is archived — treat it as a reference implementation, not a dependency.

What it does (the part worth your time): it protects a login flow against brute force and dictionary attacks by tracking failed authentication attempts and applying guard/lockout logic. That is the valuable asset here.

Minimal steps if you were on Symfony 2 (for archaeology / evaluation):

  1. composer require metaclass-nl/authentication-guard-bundle — expect constraints pinned to old Symfony 2 PHP versions; you will likely need an old PHP runtime.
  2. Register the bundle in app/AppKernel.php:
    public function registerBundles()
    {
        $bundles = [
            // ...
            new Metaclass\AuthenticationGuardBundle\MetaclassAuthenticationGuardBundle(),
        ];
        return $bundles;
    }
    
  3. Import the bundle's config into app/config/config.yml and wire the guard to your authentication provider. Read the README first for the exact config keys — they are not stable documentation and the repo is the only source of truth.
  4. Hook it into your login form / authentication listener and verify a lockout after N failed attempts.

First use case to evaluate: "lock an account or IP after X failed logins within Y minutes." Confirm that behavior works in the bundle before investing in a port.

For a Laravel developer, "Getting Started" really means: clone the repo, read Resources/config/ and the guard classes, and use it as a spec for what you will build natively (see below).

Implementation Patterns

Pattern 1 — Don't install it; port the concept

The Laravel-native equivalent of this bundle is a combination of rate limiting and the Illuminate\Auth\Events hooks. This is the pattern to reach for day-to-day:

// Register a login attempt tracker
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('login', function (Request $request) {
    $key = Str::lower($request->input('email')).'|'.$request->ip();
    return Limit::perMinute(5)->by($key);
});

Then in your LoginRequest or controller:

if (RateLimiter::tooManyAttempts($key, 5)) {
    throw ValidationException::withMessages([
        'email' => 'Too many attempts. Try again in '.RateLimiter::availableIn($key).' seconds.',
    ]);
}

On success: RateLimiter::clear($key). On failure: RateLimiter::hit($key, 900).

Pattern 2 — Event-driven attempt tracking

The bundle's structure (a guard watching authentication) maps cleanly onto Laravel events:

// EventServiceProvider
protected $listen = [
    \Illuminate\Auth\Events\Failed::class => [
        \App\Listeners\RecordFailedLogin::class,
    ],
    \Illuminate\Auth\Events\Lockout::class => [
        \App\Listeners\NotifyOfLockout::class,
    ],
];

In RecordFailedLogin, persist attempts to a table keyed by (identifier, ip) so you can implement dictionary-attack detection (many distinct passwords, same email) rather than just simple counting. That distinction is what this bundle was actually pitched at, and simple RateLimiter alone won't catch a distributed dictionary attack.

Pattern 3 — Middleware for the guard gate

Wrap protected routes in a middleware that checks an "is this identity locked" store before the auth attempt, rather than after:

class EnsureNotLocked
{
    public function handle($request, Closure $next)
    {
        $key = Str::lower($request->input('email')).'|'.$request->ip();
        abort_if(RateLimiter::tooManyAttempts($key, 5), 429);
        return $next($request);
    }
}

Pattern 4 — If you truly must run the Symfony bundle

Only in a legacy Symfony 2 app you already maintain. Treat it as one service in the container: register the bundle, point your security.yml firewall's guard/listener at it, and keep it isolated behind a firewall config block so you can swap it later. Do not spread its classes through application code — the archived status means you will replace it.

Gotchas and Tips

  • Archived + 2017 release = unmaintained security code. A brute-force guard that is itself unpatched is a liability. The whole point of the package is security; do not ship it as-is on a live login.
  • Symfony 2 is EOL. Symfony 2.8 support ended years ago. Dependency resolution will fight modern PHP and Composer 2. Expect to pin PHP 5.6/7.0-era tooling if you try to run it at all.
  • No Laravel bridge exists, and none is coming. Any "integration" is a manual port. Budget for that.
  • Config keys are undocumented beyond the README. Because the repo is archived with a single old release, don't trust blog posts or tutorials — verify against source in Resources/config/.
  • Guard state storage matters. If the bundle stores attempt counts in cache or DB, that store becomes part of your auth critical path. On a Laravel port, prefer Redis (RateLimiter default) over request-scoped state so limits survive workers/restarts.
  • IP-only lockouts are trivially bypassed (rotating IPs) and can lock out shared NAT users. The bundle's value is the identifier + IP combination; keep both dimensions when porting.
  • Watch the failure UX. A brute-force guard that reveals "account locked" vs "wrong password" leaks valid usernames. This bundle's age means it may not have addressed enumeration — check, and design a neutral response in your port.
  • Debugging lockouts in a ported Laravel setup: inspect RateLimiter::attempts($key), check your cache driver is shared across processes, and confirm Failed/Lockout listeners are actually registered — silent no-ops are the usual cause of "protection not working."
  • Extension points to steal, not adopt: the bundle's guard listener and its attempt-tracking service are worth reading as a spec. Reimplement the throttle logic natively; leave the Symfony wiring behind.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource