stanleykinkelaar / laravel-browser-sessions-lite
A lightweight Laravel package for managing browser sessions with device detection and secure logout
Fund package maintenance!
Stanley Kinkelaar
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 2
pkg:composer/stanleykinkelaar/laravel-browser-sessions-lite
Requires
- php: ^8.2|^8.3|^8.4
- illuminate/contracts: ^10.0|^11.0|^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0|^2.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.0|^7.0
- orchestra/testbench: ^9.0|^8.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0|^1.0
- phpstan/phpstan-phpunit: ^2.0|^1.0
This package is auto-updated.
Last update: 2026-01-05 19:01:48 UTC
README
Ever wondered who's logged into your app right now? π€ This lightweight Laravel package lets users see all their active browser sessions and securely log out suspicious onesβall without the bloat of heavy device detection libraries.
Perfect for apps that need Jetstream-style session management but want to keep it simple and fast.
β¨ Features
- π± No Device Detection Libraries - Lightweight regex-based detection without heavy dependencies
- π Secure by Default - Password-verified logout prevents accidental lockouts
- π¨ Beautiful UI - Jetstream-inspired Blade view with Tailwind CSS
- π JSON API Ready - Full REST API support for SPAs and mobile apps
- π Smart Device Hints - Lightweight regex-based detection (iOS, Android, browsers, OS)
- β‘ Modern Laravel - Works seamlessly with Laravel 10, 11 & 12
- π§ͺ Battle-Tested - Comprehensive Pest test suite with 100% coverage
- π― Spatie Standards - Built on
spatie/laravel-package-tools
π― Use Cases
- Security-conscious apps - Let users monitor and manage their active sessions
- Multi-device workflows - Show users where they're logged in (phone, tablet, laptop)
- Account hijacking prevention - Users can quickly log out suspicious sessions
- Jetstream alternative - Get session management without Jetstream's full stack
π¦ Requirements
| Requirement | Version |
|---|---|
| PHP | 8.2+ |
| Laravel | 10.x, 11.x, 12.x |
| Session Driver | database |
π Installation
Step 1: Install via Composer
composer require stanleykinkelaar/laravel-browser-sessions-lite
Step 2: Configure Database Sessions
This package requires Laravel's database session driver. Update your .env:
SESSION_DRIVER=database
Create the sessions table (if you haven't already):
php artisan session:table php artisan migrate
Step 3: Publish Assets (Optional)
Publish config file to customize routes and middleware:
php artisan vendor:publish --tag="browser-sessions-lite-config"
Publish views to customize the UI:
php artisan vendor:publish --tag="browser-sessions-lite-views"
βοΈ Configuration
The config file (config/browser-sessions-lite.php) allows you to customize behavior:
return [ /* * Middleware applied to browser sessions routes. * Default: ['web', 'auth'] */ 'middleware' => ['web', 'auth'], /* * URI prefix for all routes. * Default: 'user' (results in /user/browser-sessions) */ 'prefix' => 'user', ];
Pro tip: Need admin-only access? Change middleware to ['web', 'auth', 'admin']
π¨ Usage
Web UI (Blade)
The package automatically registers these routes:
| Method | URI | Description |
|---|---|---|
GET |
/user/browser-sessions |
View all sessions (Blade UI) |
DELETE |
/user/browser-sessions/others |
Logout other sessions |
Simply visit /user/browser-sessions in your browser to see the beautiful UI!
π That's it! The view looks like this:
- β List of all active sessions with device hints
- β Current device highlighted with a badge
- β IP addresses and "last active" timestamps
- β Password-protected "Log Out Other Sessions" button
- β Success/error flash messages
- β Fully responsive (mobile-friendly)
Programmatic Usage (PHP)
List Sessions for Current User
use StanleyKinkelaar\LaravelBrowserSessionsLite\Facades\LaravelBrowserSessionsLite; $sessions = LaravelBrowserSessionsLite::listForCurrentUser(); foreach ($sessions as $session) { echo $session['device_hint']; // "iOS Device", "Chrome Browser", etc. echo $session['ip_address']; // "192.168.1.1" echo $session['is_current']; // true/false echo $session['last_active_at']; // Carbon instance }
Logout Other Sessions (with password verification)
try { $deletedCount = LaravelBrowserSessionsLite::logoutOtherSessionsWithPassword('user-password'); echo "β Logged out {$deletedCount} other sessions"; } catch (\Illuminate\Validation\ValidationException $e) { echo "β Invalid password"; }
Force Logout (admin use - skips password check)
// Useful for admin panels or security automation $deletedCount = LaravelBrowserSessionsLite::forceLogoutOthersForUser($userId, 'password');
Check for Multiple Sessions
if (LaravelBrowserSessionsLite::hasMultipleSessions()) { echo "β οΈ You have active sessions on other devices"; } $count = LaravelBrowserSessionsLite::getActiveSessionCount(); echo "You have {$count} active sessions";
JSON API Usage (for SPAs & Mobile Apps)
All routes support JSON responses when using Accept: application/json header.
List Sessions (JSON)
curl -X GET https://your-app.com/user/browser-sessions \ -H "Accept: application/json" \ -H "Authorization: Bearer {token}"
Response:
{
"sessions": [
{
"id": "abc123xyz",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"last_active_at": "2024-01-15 10:30:00",
"is_current": true,
"device_hint": "Chrome Browser"
},
{
"id": "def456uvw",
"ip_address": "192.168.1.50",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)...",
"last_active_at": "2024-01-14 18:22:00",
"is_current": false,
"device_hint": "iOS Device"
}
],
"count": 2
}
Logout Other Sessions (JSON)
curl -X DELETE https://your-app.com/user/browser-sessions/others \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {token}" \ -d '{"password": "user-password"}'
Success Response:
{
"message": "Successfully logged out other browser sessions.",
"deleted_count": 2
}
Error Response (422):
{
"message": "The provided password is incorrect.",
"errors": {
"password": ["The provided password is incorrect."]
}
}
π Device Detection
The package uses simple regex patterns for device hints (no external libraries, zero bloat):
| User Agent Contains | Device Hint Shown |
|---|---|
iPhone, iPad, iPod |
iOS Device π± |
Android |
Android Device π€ |
Edg |
Edge Browser π |
Chrome |
Chrome Browser π |
Firefox |
Firefox Browser π¦ |
Safari |
Safari Browser π§ |
Windows |
Windows PC π» |
Macintosh, Mac OS |
Mac Computer π |
Linux |
Linux PC π§ |
Note: Detection order matters! Edge and Chrome are checked before Safari (since their UAs contain "Safari").
π¬ Example Integrations
Integration 1: Laravel Blade Layout
<!-- resources/views/profile/sessions.blade.php --> <x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl">Browser Sessions</h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> @include('browser-sessions-lite::browser-sessions') </div> </div> </x-app-layout>
Integration 2: Vue/React SPA
// composables/useBrowserSessions.js import { ref } from 'vue'; export function useBrowserSessions() { const sessions = ref([]); const loading = ref(false); const fetchSessions = async () => { loading.value = true; const response = await fetch('/user/browser-sessions', { headers: { 'Accept': 'application/json', 'Authorization': `Bearer ${token}` } }); const data = await response.json(); sessions.value = data.sessions; loading.value = false; }; const logoutOtherSessions = async (password) => { const response = await fetch('/user/browser-sessions/others', { method: 'DELETE', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ password }) }); if (response.ok) { await fetchSessions(); // Refresh list return await response.json(); } throw new Error('Invalid password'); }; return { sessions, loading, fetchSessions, logoutOtherSessions }; }
Integration 3: Livewire Component
namespace App\Livewire; use Livewire\Component; use StanleyKinkelaar\LaravelBrowserSessionsLite\Facades\LaravelBrowserSessionsLite; class BrowserSessions extends Component { public $password = ''; public function logoutOtherSessions() { $this->validate([ 'password' => 'required|current_password', ]); try { $count = LaravelBrowserSessionsLite::logoutOtherSessionsWithPassword($this->password); session()->flash('success', "Logged out {$count} sessions!"); $this->password = ''; } catch (\Exception $e) { $this->addError('password', 'Invalid password.'); } } public function render() { return view('livewire.browser-sessions', [ 'sessions' => LaravelBrowserSessionsLite::listForCurrentUser(), ]); } }
π€ Why No Device Detection Libraries?
This package intentionally avoids external device detection libraries like jenssegers/agent or mobiledetect/mobiledetectlib because:
β
Faster installation - No heavy dependencies to download
β
Fewer conflicts - Less chance of version mismatch issues
β
Smaller footprint - Keeps your vendor/ folder lean
β
Easier maintenance - Simple regex patterns anyone can understand
β
Focused purpose - Does one thing (session management) really well
Need advanced device detection? (browser versions, OS versions, device models, etc.) Consider using a dedicated package alongside this one. This package focuses on giving users just enough info to identify their devicesβwithout the bloat.
π§ͺ Testing
This package includes a comprehensive Pest test suite covering:
- β Repository layer (session queries, device detection)
- β Service layer (password verification, logout logic)
- β Controller layer (HTTP requests, JSON responses)
- β Integration tests (full flow from request to database)
Run Tests
# Run all tests composer test # Run with coverage report composer test-coverage # Run static analysis (PHPStan) composer analyse # Fix code style (Laravel Pint) composer format
Example Test Output
PASS Tests\Unit\SessionRepositoryTest β can get sessions for a user β can get the current session id β can delete other sessions for a user β correctly detects iOS devices β correctly detects Android devices β correctly detects Chrome browser PASS Tests\Feature\BrowserSessionsControllerTest β can view browser sessions page β can logout other sessions with valid password β cannot logout with invalid password β returns json response when requested Tests: 10 passed Time: 0.42s
π οΈ How to Test in Your Package
Since this is a Spatie-style Laravel package, testing is set up using:
- Orchestra Testbench - Simulates a Laravel app environment
- Pest PHP - Modern testing framework
- In-memory SQLite - Fast test database
Running Tests During Development
# From the package root directory: cd /path/to/laravel-browser-sessions-lite # Install dependencies composer install # Run tests composer test # Watch tests (with Pest --watch, if installed globally) pest --watch
Testing in a Real Laravel App
Want to test this package in your actual Laravel app before release?
Option 1: Composer Local Path
Add to your Laravel app's composer.json:
{
"repositories": [
{
"type": "path",
"url": "../laravel-browser-sessions-lite"
}
],
"require": {
"stanleykinkelaar/laravel-browser-sessions-lite": "@dev"
}
}
Then run:
composer update stanleykinkelaar/laravel-browser-sessions-lite
Option 2: Testbench Workbench (Spatie Style)
Use Orchestra Testbench's workbench feature:
cd laravel-browser-sessions-lite
composer run prepare
php vendor/bin/testbench serve
Visit http://localhost:8000/user/browser-sessions to test the UI!
π Architecture Overview
This package follows Spatie conventions and clean architecture:
src/
βββ LaravelBrowserSessionsLiteServiceProvider.php # Package registration
βββ Http/
β βββ Controllers/
β βββ BrowserSessionsController.php # Handles web + JSON requests
βββ Services/
β βββ BrowserSessions.php # Business logic (logout, verification)
βββ Repositories/
β βββ SessionRepository.php # Database queries + device hints
βββ Facades/
βββ LaravelBrowserSessionsLite.php # Facade for easy access
Design principles:
- β Repository pattern - Separates database logic from business logic
- β Service layer - Handles password verification and authentication
- β Single responsibility - Each class does one thing well
- β Dependency injection - Fully testable and mockable
- β Laravel conventions - Feels native to Laravel
π Security Best Practices
This package is designed with security in mind:
β
Password verification required - Users must enter their password to log out other sessions
β
Laravel's current_password rule - Uses built-in validation
β
Auth middleware by default - Routes protected out of the box
β
CSRF protection - Form submissions are CSRF-protected
β
Session rehashing - Uses Laravel's Auth::logoutOtherDevices()
Reporting Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
π€ Contributing
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Run the test suite (
composer test) - Fix code style (
composer format) - Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please see CONTRIBUTING.md for detailed guidelines.
π Changelog
All notable changes are documented in CHANGELOG.md.
π License
The MIT License (MIT). See LICENSE.md for details.
π Credits
- Stanley Kinkelaar - Creator & Maintainer
- Inspired by Laravel Jetstream's session management
- Built on Spatie's Laravel Package Tools
- All contributors listed in contributors
β Show Your Support
If this package helped you, consider:
- β Starring the repo on GitHub
- π¦ Sharing it on Twitter
- β Buying me a coffee (coming soon!)
Made with β€οΈ by Stanley Kinkelaar
Built for the Laravel community π