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

Laravel Site Protection Laravel Package

elic-dev/laravel-site-protection

A Laravel package for adding configurable site-wide protection to your application. It uses middleware and Laravel-native configuration to restrict access, shield staging or private sites, and keep unwanted visitors out while authorized users continue smoothly. Simple setup and sensible defaults.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package

    composer require elic-dev/laravel-site-protection
    
  2. Publish the config (and optionally the view)

    Check the README for the exact publish tag/provider, but it will be one of:

    php artisan vendor:publish --tag=site-protection-config
    php artisan vendor:publish --tag=site-protection-views
    # or, if no tags are defined:
    php artisan vendor:publish --provider="ElicDev\SiteProtection\SiteProtectionServiceProvider"
    
  3. Set the password via environment

    The package is config-driven, so the password should come from .env rather than a committed config file:

    SITE_PROTECTION_ENABLED=true
    SITE_PROTECTION_PASSWORD=correct-horse-battery-staple
    
  4. Register the middleware

    For a whole-site gate, register it globally (Laravel 11+ bootstrap/app.php):

    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(\ElicDev\SiteProtection\Http\Middleware\ProtectSite::class);
    })
    

    Or, more commonly, apply it to a route group so you can carve out exceptions.

  5. Where to look first

    • config/site-protection.php — enable flag, password, excluded paths, view name, cookie/session settings. This is the source of truth for how the package behaves.
    • The package's middleware class — this is where the "is the visitor already authorized?" check lives, and where you'll extend behavior.
    • The bundled Blade view — the fastest place to re-skin the password form.
  6. First use case

    The canonical fit is a staging / preview / client-review environment: keep the site publicly reachable but behind a shared password so search engines, crawlers, and casual visitors can't see it. It is not a replacement for laravel/auth — it's a single shared gate, not per-user accounts.

Implementation Patterns

Environment-scoped enabling. The cleanest pattern is to enable the gate only where it makes sense:

// config/site-protection.php
'enabled' => env('SITE_PROTECTION_ENABLED', app()->environment() !== 'production'),

Then set SITE_PROTECTION_ENABLED=true in staging/preview .env files and leave it false in local and production. Review apps (Forge, Vapor, Heroku review apps, Ploi) get a per-deploy password injected as an env var — a different password per preview environment is a cheap way to revoke access when a review is done.

Route-group gating instead of global middleware. If only part of the app needs protecting (e.g. an internal dashboard or a pre-launch marketing site), wrap the group:

Route::middleware('site-protection')->group(function () {
    // protected routes
});

and alias the middleware in bootstrap/app.php / Kernel.php.

Exclusions are the main integration point. You will immediately need to exclude:

  • The package's own login/POST route (otherwise you get a redirect loop).
  • Health checks (/up, /health).
  • Webhooks (Stripe, GitHub, Slack) — they can't fill in a form.
  • Asset paths if you serve them through Laravel rather than the web server.
  • sitemap.xml / robots.txt if you want them reachable.

Most packages of this shape expose an except array in config; prefer that over writing a custom middleware.

Re-skin the form. Publish the view and match it to your app's layout. Keep the form posting to the package's route with @csrf intact — the package handles the password check, you only need to own the markup.

Combine, don't replace, with auth. A common production pattern is site-protection on the whole site plus auth on admin routes. The site gate stops the public; auth still does per-user authorization. Don't try to bolt user accounts onto this package.

Testing. In phpunit.xml, set SITE_PROTECTION_ENABLED=false for the test suite, or call $this->withoutMiddleware(ProtectSite::class) in feature tests. For tests that exercise the gate itself, set the password in the test env and assert the redirect-to-form / successful-post flow explicitly.

Automation / smoke tests. If CI hits a staging URL, either disable protection for the CI IP range (if the package supports IP allowlists — check the config) or have the smoke test POST the password first and reuse the session cookie.

Gotchas and Tips

  • config:cache will bite you. After changing SITE_PROTECTION_PASSWORD or the enable flag, run php artisan config:cache (or config:clear) on the server. A stale cached config is the #1 reason "I changed the password and nothing happened."
  • Session and cookie scope. The "already authenticated" state is almost certainly session/cookie-based. Changing SESSION_DRIVER, SESSION_DOMAIN, or APP_KEY will invalidate existing visitors' access — expect everyone to be re-prompted after a deploy that touches those. If you're behind a proxy or load balancer, make sure TrustProxies is configured so the secure-cookie flag is set correctly.
  • Redirect loops. If the login route or the POST endpoint isn't excluded from the middleware, the gate redirects to itself forever. Symptom: ERR_TOO_MANY_REDIRECTS on the password page. Fix in the except config, not by hacking the middleware.
  • CSRF failures on the form. If you publish and modify the view, don't drop @csrf. A 419 on submit is nearly always this.
  • No brute-force protection by default. A shared password form is a guessing target. Put the login POST route behind throttle: middleware, and pick a long random password rather than something memorable.
  • Not real security. This is a "keep the site out of Google and away from casual eyes" tool. It does not encrypt content, does not do per-user permissions, and doesn't protect against someone who already has the URL and password. Never use it as the only gate on PII, admin panels, or anything compliance-relevant.
  • Middleware ordering matters. If you also use auth, verified, or custom middleware, the site gate should run early (global or first in the group) so unauthenticated visitors see the password form rather than a login redirect.
  • Expose a logout/exit route. Users on shared machines need a way to clear the gate. Either use the package's built-in forget/logout route or add a small route that flushes the session key the package sets.
  • Search engine hygiene. On a protected environment, also set X-Robots-Tag: noindex and a Disallow: / robots rule. The password form is a nice signal but isn't a crawler directive.
  • Octane / long-running workers. Config is read per-request in normal FPM, but with Octane you must restart workers after env/config changes (php artisan octane:reload) — same class of bug as config:cache.
  • Extension points worth knowing: the published config (password, enabled flag, exclusions, view), the published Blade view (branding), and the middleware class itself (subclass it if you need custom logic like IP allowlists or a second password for a specific client). Prefer config over forking; the package is small and 45 stars means it's not going to absorb your patches quickly.
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.
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen