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

Nova Aegis Smart Ip Blocker Laravel Package

wobqqq/nova-aegis-smart-ip-blocker

A Laravel Nova package for smart IP blocking that helps protect Laravel apps by detecting suspicious or abusive requests, automatically blocking offending IPs, and letting admins manage blocked addresses, whitelists, and security events from the Nova panel.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package and publishing its assets:

composer require <vendor>/smart-ip-blocker
php artisan vendor:publish --tag="smart-ip-blocker-config"
php artisan vendor:publish --tag="smart-ip-blocker-migrations"
php artisan migrate

Look first at config/smart-ip-blocker.php — this is where the detection window, thresholds, and storage driver live. Then inspect the visits table migration and the Visit model, because that model is the core domain object: every request the middleware observes is recorded as a Visit, and the blocker reasons over those records rather than over the raw request.

Your first use case is almost always protecting authentication and form endpoints from credential-stuffing or scraping. Register the middleware on the routes you care about:

Route::middleware('smart-ip-blocker')->group(function () {
    Route::post('/login', [LoginController::class, 'store']);
    Route::post('/register', [RegisterController::class, 'store']);
});

Once that is in place, hit a protected route a few times and inspect the visits table. If rows appear and the response flips to a block after your configured threshold, the pipeline is wired correctly.

Implementation Patterns

Middleware-first, action-second. The primary integration is the HTTP middleware, but the underlying SmartIpBlocker is a resolvable service. Inject it when you need to make blocking decisions outside the request lifecycle (console commands, jobs, custom guards):

public function handle(SmartIpBlocker $blocker, Visit $visit)
{
    if ($blocker->shouldBlock($visit)) {
        // custom response
    }
}

Note the v1.2.0 signature: the blocker consumes a Visit rather than the request. If you previously resolved the blocker and passed $request, construct or fetch a Visit for the IP you are evaluating instead.

Time-aware logic via the PSR clock. The blocker reads "now" from a PSR-20 ClockInterface, not from now(). This is the cleanest extension point in the package. In tests, bind a frozen clock so window-based rules are deterministic:

$this->app->instance(ClockInterface::class, new FrozenClock(new DateTimeImmutable('2024-01-01 12:00:00')));

In production the package ships a system clock binding, so you normally do nothing — but if your app already binds ClockInterface, the blocker will honour it.

Disabling programmatically. The disable path is encapsulated in the DisableSmartIpBlocker action. Call it directly from an admin controller or a test rather than manipulating config at runtime:

app(DisableSmartIpBlocker::class)->execute();

The bundled artisan command is a thin wrapper around this action. If you need to disable blocking for a support session, invoke the command; if you need to disable it in a test, invoke the action. Keeping that distinction avoids stale config caches.

Thresholds and windows in config. Tune the number of allowed visits and the lookback period in config rather than in code. Because the blocker queries the visits table, keep an index on (ip, created_at) (the published migration does this) and consider pruning old rows on a schedule:

Schedule::command('model:prune', ['--model' => [Visit::class]])->daily();

Whitelisting. For internal services, health checks, or your own office IPs, prefer an allow-list middleware that runs before the blocker rather than early-returning inside your controllers. This keeps the blocking decision in one place.

Gotchas and Tips

  • The v1.2.0 refactor is internal but touches DI. The blocker now type-hints Visit and the disable command delegates to DisableSmartIpBlocker. Applications that only use the middleware and config are unaffected. If you extended SmartIpBlocker, overrode the command, or resolved the blocker manually with a request argument, update those call sites.
  • IP resolution behind proxies. The package records whatever IP the request reports. Behind a load balancer or CDN, configure TrustProxies correctly or every visit will share the proxy's IP and your thresholds will trip for everyone.
  • Clock binding is app-wide. If you bind a custom ClockInterface for testing and forget to restore it, other time-sensitive code in the same test suite may see frozen time. Bind it in the test that needs it, not in a base test case shared across suites.
  • Migrations are published, not auto-loaded. Forgetting php artisan migrate after install produces an empty visits table and the blocker will silently never trigger — there is nothing to count. Watch for this in CI.
  • Config caching. If you change thresholds in production, run php artisan config:cache as part of deploy. Editing the config file on a cached app has no effect and is a common "why is it still blocking" cause.
  • Blocking is a response concern. The middleware returns a block response; it does not throw. If you need custom block pages or JSON responses for API routes, publish and override the response configuration, or wrap the middleware with your own that inspects the blocker result.
  • Prune aggressively. The visits table grows with traffic. Without pruning, lookback queries degrade over months. Schedule pruning and monitor table size.
  • Test the disabled path explicitly. Because DisableSmartIpBlocker is a separate action, assert both that blocking occurs when enabled and that the action short-circuits it. This catches regressions from the v1.2.0 command rewiring.
  • Extension point to prefer. When you need custom blocking logic, compose around SmartIpBlocker (decorator or subclass) rather than editing published config or forking middleware — the package's internal refactors (as in 1.2.0) are safer to absorb when your integration sits at the public service boundary.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource