laravel-idle-client maintained by angga
Laravel Idle Client
Automatically detect idle users and log them out after a configurable inactivity timeout. Supports both backend (middleware) and frontend (pure JS timer) validation with a warning countdown dialog before logout.
Features
- Backend middleware — validates
idle_last_activityon every request, forces logout server-side - Frontend pure timer — no AJAX polling; detects activity via DOM events
- Multi-tab sync —
localStorageevents keep all open tabs in sync - Warning dialog — countdown popup N minutes before session expires
- Remember me aware — users with an active "remember me" cookie are exempt
- Laravel 5.6 – 12.x compatible, PHP 7.2+
- Configurable entirely via
.env
Requirements
| Dependency | Version |
|---|---|
| PHP | ≥ 7.2 |
| Laravel | 5.6 – 12.x |
Installation
composer require angga/laravel-idle-client
Laravel 5.5+ auto-discovers the service provider. For older versions add it manually:
// config/app.php
'providers' => [
Angga\IdleClient\IdleClientServiceProvider::class,
],
Publish assets (required)
The JavaScript file must be available in public/vendor/idle-client/:
php artisan vendor:publish --tag=idle-client-assets
Publish config (optional)
php artisan vendor:publish --tag=idle-client-config
Configuration
Add the following keys to your .env file (all optional — defaults shown):
IDLE_TIMEOUT_MINUTES=30 # Minutes of inactivity before logout
IDLE_WARNING_MINUTES=1 # Minutes before timeout to show warning (0 = disable)
IDLE_REDIRECT_URL=/logout # Where to redirect after logout
IDLE_TIMEOUT_MESSAGE="Your session has expired due to inactivity. Please login again."
# Package logout route (GET /idle-client/logout)
IDLE_ENABLE_ROUTES=false
IDLE_ROUTE_PREFIX=idle-client
# Warning dialog texts
IDLE_WARNING_TITLE="Session Expiring Soon"
IDLE_WARNING_MESSAGE="Your session is about to expire due to inactivity."
IDLE_COUNTDOWN_TEXT="You will be logged out in {seconds} seconds."
IDLE_STAY_BUTTON_TEXT="Stay Logged In"
IDLE_LOGOUT_BUTTON_TEXT="Logout Now"
Usage
1. Apply the middleware to your routes
The package registers a named middleware idle.timeout. Add it to any route group that requires idle detection:
// routes/web.php
Route::middleware(['auth', 'idle.timeout'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/profile', [ProfileController::class, 'show']);
// ...
});
You can also scope it to a specific auth guard:
Route::middleware(['auth:admin', 'idle.timeout:admin'])->group(function () {
// admin routes
});
2. Add the script directive to your Blade layout
Place @idleScript at the end of <body> in your authenticated layout. The directive outputs the <script> tag and initialises the JS timer automatically.
<!DOCTYPE html>
<html>
<head>...</head>
<body>
@yield('content')
{{-- Idle timeout script (only on authenticated pages) --}}
@idleScript
</body>
</html>
You can override any option per-page:
@idleScript(['timeout' => 15, 'warning' => 2])
Available JS options mirror the config keys (camelCase):
| Option | Default | Description |
|---|---|---|
timeout |
30 |
Idle timeout in minutes |
warning |
1 |
Minutes before timeout to show dialog |
redirectUrl |
(route) | URL to navigate to on logout |
warningTitle |
'Session Expiring Soon' |
Dialog heading |
warningMessage |
'...' |
Dialog body text |
countdownText |
'...{seconds}...' |
Use {seconds} as placeholder |
stayButtonText |
'Stay Logged In' |
Stay button label |
logoutButtonText |
'Logout Now' |
Logout button label |
3. Display the timeout flash message (optional)
When the backend middleware forces a logout it sets a idle_timeout flash message on the session:
@if(session('idle_timeout'))
<div class="alert alert-warning">
{{ session('idle_timeout') }}
</div>
@endif
How It Works
User opens page
│
▼
Backend middleware runs on every request
├─ User not logged in? → pass through
├─ Remember me cookie present? → pass through (exempt)
├─ No idle_last_activity yet? → set it, pass through
├─ Time elapsed < timeout? → update timestamp, pass through
└─ Time elapsed ≥ timeout? → force logout → redirect
Frontend (pure timer, no AJAX)
├─ Tracks mouse / keyboard / scroll / touch events
├─ Syncs last-activity timestamp to localStorage
├─ Other tabs listen via storage event → timer reset across tabs
├─ At (timeout − warning) minutes → show countdown warning dialog
│ ├─ "Stay Logged In" → reset timer, close dialog
│ └─ "Logout Now" → redirect to logout URL
└─ At timeout minutes → redirect to logout URL
Security Notes
- The backend middleware is the authoritative guard. Even if a user disables JavaScript, the server will still force logout on the next request after the timeout.
- The
idle-client/logoutroute invalidates the session and regenerates the CSRF token before redirecting, preventing session fixation. - Remember-me detection checks for cookies whose name starts with
remember_(Laravel's default prefix). Override the middleware if your application uses a non-standard cookie name.
Changelog
v1.0.0
- Initial release
License
MIT © Angga