Available for select projects New York · Working worldwide
Rappasoft LLC
Menu

Laravel Lockout / Documentation / v6

Usage

Installation, configuration, and usage guidance maintained with the project.

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:

IPv4 and IPv6 addresses and CIDR ranges are supported. Malformed CIDR masks are ignored.

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 supported
4 '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:

* matches any path characters. Other characters, including dots, are matched literally.

1'route_patterns' => [
2 'api/*', // All API routes
3 'health', // Health check
4 'admin/*', // All admin routes
5],

Route Names

Whitelist routes by name:

Names are matched against the route for the current request, including when Lockout runs as global middleware.

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": true
5}

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:

The enable and disable commands automatically clear the lockout status cache. --clear-cache remains accepted for existing scripts.

1php artisan lockout:enable --clear-cache
2php 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 enabled
  • Rappasoft\Lockout\Events\LockoutDisabled - Fired when lockout is disabled
  • Rappasoft\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

These commands update the application's active environment file, preserve its file permissions, and clear any cached Laravel configuration. They fail if the environment file is missing or cannot be updated. Run php artisan config:cache afterwards if your deployment uses cached configuration, and restart long-running workers or Octane processes so they reload the setting. If your deployment supplies APP_READ_ONLY through external environment variables, update that setting through your deployment instead.

Enable Lockout

1php artisan lockout:enable

Options:

  • --clear-cache - Accepted for existing scripts; the lockout cache is always cleared

Disable Lockout

1php artisan lockout:disable

Options:

  • --clear-cache - Accepted for existing scripts; the lockout cache is always cleared

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: abort
10 Health Check: Yes
11 Cache Enabled: Yes

Blade Directive

Conditionally render content based on lockout status:

1@readonly
2 <div class="alert alert-warning">
3 Application is currently in read-only mode.
4 </div>
5@else
6 <div class="alert alert-info">
7 Application is fully operational.
8 </div>
9@endreadonly

Best Practices

  1. Use IP Whitelist for Maintenance: Whitelist your IP before enabling lockout to ensure you can still access the application.

  2. Use Health Check for Monitoring: Configure your monitoring tools to check the /health endpoint.

  3. Enable Caching in Production: Improve performance by enabling cache for lockout status.

  4. Use Events for Logging: Listen to RequestBlocked events to track blocked requests.

  5. Customize Response for Better UX: Use view responses for web requests and JSON for API requests.

  6. Test Before Production: Always test lockout in a staging environment first.