angga / laravel-idle-client
Detect idle users and automatically logout after inactivity timeout in Laravel
Package info
github.com/aanggakrishna/laravel-iddle-client
Language:JavaScript
pkg:composer/angga/laravel-idle-client
Requires
- php: >=7.2
- illuminate/auth: ^5.6|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0
- illuminate/http: ^5.6|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0
- illuminate/routing: ^5.6|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0
- illuminate/session: ^5.6|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0
- illuminate/support: ^5.6|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0
README
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