⚠️ DEVELOPMENT TOOL - NOT FOR PRODUCTION USE⚠️ This package is designed for local development and staging environments only. It allows developers to quickly switch between user accounts for testing and debugging purposes.
DO NOT enable this package in production environments unless you have a specific, well-understood use case and have implemented additional security measures.
This package provides Laravel integration for the Generic User Switcher library. It includes a user provider implementation that fetches users from your Laravel database and an impersonator implementation using Laravel's session and authentication system.
- Seamless Integration: Automatically binds
UserProviderInterfaceandImpersonatorInterfaceto Laravel implementations. - Configurable: Easily configure which User model to use.
- Environment Control: Restrict user switching to specific environments (e.g.,
local,staging) to prevent accidents in production. - Session-based Impersonation: Securely impersonates users by maintaining the original user's ID in the session.
Install as a development dependency:
composer require cdoebler/laravel-user-switcher --devFor staging environments that use production dependencies, install normally:
composer require cdoebler/laravel-user-switcherThe service provider is auto-discovered by Laravel.
The package is disabled by default. Enable it in your development .env:
USER_SWITCHER_ENABLED=truePublish the configuration file to config/user-switcher.php using the following command:
php artisan vendor:publish --provider="Cdoebler\LaravelUserSwitcher\UserSwitcherServiceProvider" --tag="config"The configuration file allows you to customize the package behavior.
| Option | Description | default |
|---|---|---|
user_model |
The Eloquent model class for your users. | App\Models\User |
enabled |
master switch to enable/disable the functionality. | env('USER_SWITCHER_ENABLED', false) |
environments |
Comma-separated list of allowed environments. | env('USER_SWITCHER_ENVIRONMENTS', 'local,testing') |
auto_inject |
Automatically inject the switcher widget into rendered pages. | env('USER_SWITCHER_AUTO_INJECT', true) |
authorization_callback |
Callback function to determine if user switching is allowed. | null |
USER_SWITCHER_ENABLED=true
USER_SWITCHER_ENVIRONMENTS="local,testing"
USER_SWITCHER_AUTO_INJECT=trueThis package is intended to be used with the Generic User Switcher frontend or logic. Once installed, it handles the backend logic for:
- Retrieving Users: It uses your configured Eloquent model to list available users for switching.
- Impersonation: It handles the
loginUsingIdlogic and stores the original user in the session to allow switching back.
If you need to use the interfaces directly in your code, you can inject them:
use Cdoebler\GenericUserSwitcher\Interfaces\UserProviderInterface;
use Cdoebler\GenericUserSwitcher\Interfaces\ImpersonatorInterface;
public function index(UserProviderInterface $userProvider, ImpersonatorInterface $impersonator)
{
// Get all users
$users = $userProvider->getUsers();
// Check if currently impersonating
if ($impersonator->isImpersonating()) {
// ...
}
}By default, user switching is disabled (enabled defaults to false) and restricted to local and testing environments. You can customize this using the enabled and environments config options, or implement custom authorization logic using the authorization_callback configuration option.
The authorization_callback allows you to define custom logic to determine whether user switching should be allowed. This is useful when you want to restrict switching based on user roles, permissions, or other criteria.
// config/user-switcher.php
return [
// ... other config options
'authorization_callback' => function (\Illuminate\Http\Request $request) {
// Only allow switching if the authenticated user is an admin
return $request->user()?->isAdmin() ?? false;
},
];// config/user-switcher.php
return [
// ... other config options
'authorization_callback' => function (\Illuminate\Http\Request $request) {
// Check if user has the 'switch-users' permission
return $request->user()?->can('switch-users') ?? false;
},
];// config/user-switcher.php
return [
// ... other config options
'authorization_callback' => function (\Illuminate\Http\Request $request) {
// Allow in local/staging OR if user is admin in production
if (app()->environment(['local', 'staging'])) {
return true;
}
return $request->user()?->isAdmin() ?? false;
},
];// config/user-switcher.php
return [
// ... other config options
'authorization_callback' => function (\Illuminate\Http\Request $request) {
return Gate::allows('switch-users');
},
];Then define the gate in your AuthServiceProvider:
use Illuminate\Support\Facades\Gate;
Gate::define('switch-users', function ($user) {
return $user->hasRole('admin') || $user->hasRole('developer');
});Important: When you're impersonating another user, authorization checks are based on the original user (the one who started impersonation), not the currently impersonated user.
This means:
- If an admin (ID: 1) switches to a regular user (ID: 5), the switcher widget remains visible
- The admin can continue switching to other users
- Authorization is always checked against the original admin, not the impersonated user
This prevents the common issue where the switcher disappears after switching to an unauthorized user.
// config/user-switcher.php
'authorization_callback' => function (\Illuminate\Http\Request $request) {
return $request->user()?->isAdmin() ?? false;
},- Admin (authorized) logs in → Widget appears ✅
- Admin switches to Regular User (unauthorized) → Widget still appears ✅
- Admin can switch back or to other users ✅
- Regular User logs in directly → Widget does not appear ✅
If authorization_callback is null or not set, the package uses the enabled and environments config options to determine if user switching is allowed.
The package includes built-in security measures:
- Session Fixation Protection: Regenerates session ID after impersonation actions
- Input Validation: Validates user identifiers (trims whitespace, rejects empty/overly long values)
Recommendations:
- Restrict to non-production environments using the
environmentsconfig - Implement authorization checks using the
authorization_callback - Consider audit logging for compliance (see base package documentation)
composer testThe MIT License (MIT). Please see License File for more information.