christhompsontldr/impersonate
Laravel package to let authorized users impersonate other accounts for support and troubleshooting. Provides start/stop impersonation helpers, middleware/guards integration, and easy checks to ensure only permitted roles can switch users safely.
Installation
composer require christhompsontldr/impersonate
Publish the config file (if needed):
php artisan vendor:publish --provider="ChrisThompsonTLDR\Impersonate\ImpersonateServiceProvider"
Configure Middleware
Add the Impersonate middleware to your routes or HTTP kernel:
// app/Http/Kernel.php
protected $routeMiddleware = [
'impersonate' => \ChrisThompsonTLDR\Impersonate\Middleware\Impersonate::class,
];
Or in routes/web.php:
Route::middleware(['auth', 'impersonate'])->group(function () {
// Impersonation-enabled routes
});
First Use Case Trigger impersonation via a route:
Route::get('/impersonate/{user}', function ($user) {
return \ChrisThompsonTLDR\Impersonate\Facades\Impersonate::impersonate($user);
})->middleware(['auth', 'impersonate']);
Or programmatically:
use ChrisThompsonTLDR\Impersonate\Facades\Impersonate;
Impersonate::impersonate($targetUser);
Impersonation Flow
auth()->user()->can('impersonate')).Impersonate::impersonate($user)->redirectTo('/dashboard');
/impersonate/stop).Route Integration
Route::middleware(['auth', 'can:impersonate-others'])->group(function () {
Route::post('/impersonate/{user}', [ImpersonateController::class, 'impersonate']);
});
public function impersonate(User $user) {
return Impersonate::impersonate($user)->redirectTo(request()->header('Referer'));
}
Session Management
config/impersonate.php:
'session_key' => 'impersonate_user_id',
View Integration
@if(auth()->check() && auth()->user()->isImpersonating())
<div class="impersonating-badge">
Impersonating: {{ auth()->user()->impersonatedUser->name }}
<a href="/impersonate/stop">Stop</a>
</div>
@endif
API Usage
return response()->json([
'user' => auth()->user(),
'is_impersonating' => auth()->user()->isImpersonating(),
]);
Session Expiry
file, database) persist across requests.SESSION_DRIVER=database in .env if using file sessions.Middleware Order
Impersonate middleware after auth but before route-specific middleware to avoid conflicts.$router->middlewareGroup('admin', [
\App\Http\Middleware\Authenticate::class,
\ChrisThompsonTLDR\Impersonate\Middleware\Impersonate::class,
// Other middleware...
]);
User Model Assumptions
User model has:
id as the primary key.name attribute for display.User model or override the facade methods:
Impersonate::impersonate($user)->setDisplayAttribute('username');
CSRF Token Issues
Impersonate::impersonate()->withoutRedirect() for AJAX calls.Permission Bypass
event(new UserImpersonated(auth()->user(), $targetUser));
admin).Check Session Data
config('impersonate.session_key')) to verify impersonation state:
dd(session(config('impersonate.session_key')));
Middleware Debugging
public function handle($request, Closure $next) {
\Log::info('Impersonate middleware triggered');
return $next($request);
}
Redirect Loops
redirectTo() paths or session conflicts.Custom Redirect Logic
redirectTo() method:
Impersonate::impersonate($user)->redirectTo(fn () => route('admin.dashboard'));
Event Listeners
// EventServiceProvider
protected $listen = [
\ChrisThompsonTLDR\Impersonate\Events\UserImpersonated::class => [
\App\Listeners\LogImpersonation::class,
],
];
Database Logging
user_impersonations table:
Impersonate::impersonate($user)->logImpersonation();
Multi-Tenant Support
config(['impersonate.session_key' => 'tenant_' . tenant()->id . '_impersonate_user_id']);
Impersonation Limits
if (auth()->user()->isImpersonating()) {
abort(403, 'Cannot impersonate while already impersonating.');
}
How can I help you explore Laravel packages today?