๐ Enjoying this package? Consider sponsoring me on GitHub or buying me a beer.
Usage
Quick Start
Enable Lockout
Add to your .env file:
1APP_READ_ONLY=true
By default, only pages accessed with GET requests will be allowed. All other request types (POST, PUT, PATCH, DELETE) will be blocked with a 401 Unauthorized response.
Disable Lockout
1APP_READ_ONLY=false
Or use the Artisan command:
1php artisan lockout:disable
Basic Configuration
Allow Login During Lockout
To allow users to log in and view secure areas (but still only allow GET requests after login):
1APP_READ_ONLY_LOGIN=true
You can customize your login/logout paths in the configuration file if they differ from Laravel defaults.
Locking Specific GET Pages
Block access to specific pages even for GET requests:
1'pages' => [2 'register',3 'subscribe',4 'admin/settings',5],
Whitelisting Specific Routes
Allow specific routes to bypass lockout:
1'whitelist' => [2 'post' => 'password/confirm',3 'put' => 'profile/update',4],
Advanced Features
IP Whitelist/Blacklist
IP Whitelist
Allow specific IP addresses to bypass lockout completely:
Via .env:
1LOCKOUT_IP_WHITELIST=127.0.0.1,192.168.1.100
Via Config:
1'ip_whitelist_array' => [2 '127.0.0.1',3 '192.168.1.0/24', // CIDR notation supported4 '10.0.0.0/8',5],
IP Blacklist
Block specific IP addresses even when lockout is disabled:
Via .env:
1LOCKOUT_IP_BLACKLIST=192.168.1.50
Via Config:
1'ip_blacklist_array' => [2 '192.168.1.50',3 '10.0.0.100/24',4],
Role-Based Exceptions
Allow users with specific roles to bypass lockout:
1'allowed_roles' => [2 'admin',3 'super-admin',4 'maintenance',5],
The package supports:
- Laravel Bouncer
- Spatie Permission
- Simple role attributes (
$user->role) - Roles relationships
Custom Response Types
View Response
Show a custom maintenance page:
1'response_type' => 'view',2'response_view' => 'lockout::maintenance',3'response_message' => 'We are currently performing maintenance.',4'response_code' => 503,
Publish the view to customize:
1php artisan vendor:publish --tag=lockout-views
JSON Response
Return JSON for API requests:
1'response_type' => 'json',2'response_code' => 503,
API-Specific Handling
Automatically detect and handle API requests differently:
1'api_enabled' => true,2'api_response_type' => 'json',3'api_response_message' => [4 'message' => 'Application is in maintenance mode.',5 'status' => 'maintenance',6],
Route Patterns and Names
Route Patterns
Whitelist routes by pattern:
1'route_patterns' => [2 'api/*', // All API routes3 'health', // Health check4 'admin/*', // All admin routes5],
Route Names
Whitelist routes by name:
1'route_names' => [2 'health.check',3 'api.status',4 'admin.dashboard',5],
Health Check Endpoint
A health check endpoint is automatically registered at /health (configurable):
1GET /health
Response:
1{2 "status": "ok",3 "timestamp": "2025-01-15T10:30:00Z",4 "lockout_enabled": true5}
Disable or customize:
1'health_check_enabled' => true,2'health_check_path' => 'health',
Cache Integration
Improve performance by caching lockout status:
1'cache_enabled' => true,2'cache_key' => 'lockout.status',3'cache_ttl' => 60, // seconds
Disable caching:
1'cache_enabled' => false,
Clear cache manually:
1php artisan cache:clear
Or when enabling/disabling:
1php artisan lockout:enable --clear-cache2php artisan lockout:disable --clear-cache
Event System
The package fires events that you can listen to:
Available Events
Rappasoft\Lockout\Events\LockoutEnabled- Fired when lockout is enabledRappasoft\Lockout\Events\LockoutDisabled- Fired when lockout is disabledRappasoft\Lockout\Events\RequestBlocked- Fired when a request is blocked
Example Listener
1use Rappasoft\Lockout\Events\RequestBlocked; 2use Illuminate\Support\Facades\Log; 3 4class LogBlockedRequests 5{ 6 public function handle(RequestBlocked $event) 7 { 8 Log::warning('Request blocked', [ 9 'path' => $event->request->path(),10 'method' => $event->request->method(),11 'ip' => $event->request->ip(),12 'reason' => $event->reason,13 ]);14 }15}
Register in EventServiceProvider:
1protected $listen = [2 RequestBlocked::class => [3 LogBlockedRequests::class,4 ],5];
Disable events:
1'fire_events' => false,
Artisan Commands
Enable Lockout
1php artisan lockout:enable
Options:
--clear-cache- Clear the lockout cache after enabling
Disable Lockout
1php artisan lockout:disable
Options:
--clear-cache- Clear the lockout cache after disabling
Check Status
1php artisan lockout:status
Output:
1Lockout Status: 2โโโโโโโโโโโโโโโโโ 3Enabled: Yes 4Cached: Yes 5 6Configuration: 7 Allow Login: Yes 8 Locked Types: post, put, patch, delete 9 Response Type: abort10 Health Check: Yes11 Cache Enabled: Yes
Blade Directive
Conditionally render content based on lockout status:
1@readonly2 <div class="alert alert-warning">3 Application is currently in read-only mode.4 </div>5@else6 <div class="alert alert-info">7 Application is fully operational.8 </div>9@endreadonly
Best Practices
-
Use IP Whitelist for Maintenance: Whitelist your IP before enabling lockout to ensure you can still access the application.
-
Use Health Check for Monitoring: Configure your monitoring tools to check the
/healthendpoint. -
Enable Caching in Production: Improve performance by enabling cache for lockout status.
-
Use Events for Logging: Listen to
RequestBlockedevents to track blocked requests. -
Customize Response for Better UX: Use view responses for web requests and JSON for API requests.
-
Test Before Production: Always test lockout in a staging environment first.