evo-mark/laravel-impersonate
Impersonate Laravel users in one click. Add a trait to your User model to start/stop impersonation, with authorization hooks, middleware, events, Blade helpers, and configurable strategies. Supports Laravel 10–11 and PHP 8.2+.
composer require evo-mark/laravel-impersonate
config/app.php:
'providers' => [
// ...
EvoMark\Impersonate\ImpersonateServiceProvider::class,
],
User model:
use EvoMark\Impersonate\Models\Impersonate;
class User extends Authenticatable
{
use Impersonate;
// ...
}
Auth::user()->impersonate($otherUser);
Auth::user()->leaveImpersonation();
Add the built-in route macro to your routes/web.php:
Route::impersonate();
Now, you can generate impersonation links:
route('impersonate', $userId); // Impersonate user
route('impersonate.leave'); // Leave impersonation
Impersonation Logic:
impersonate() method on the authenticated user:
Auth::user()->impersonate($targetUser);
Auth::user()->leaveImpersonation();
if (Auth::user()->isImpersonating()) { ... }
Authorization:
canImpersonate() in your User model to restrict who can impersonate:
public function canImpersonate()
{
return $this->is_admin;
}
canBeImpersonated() to restrict who can be impersonated:
public function canBeImpersonated()
{
return $this->is_impersonatable;
}
Blade Directives:
@canImpersonate
<a href="{{ route('impersonate', $user->id) }}">Impersonate</a>
@endcanImpersonate
@canBeImpersonated($user)
<a href="{{ route('impersonate', $user->id) }}">Impersonate</a>
@endcanBeImpersonated
@impersonating
<a href="{{ route('impersonate.leave') }}">Leave Impersonation</a>
@endimpersonating
Custom Redirects: Publish the config and customize redirects:
php artisan vendor:publish --tag=impersonate
Update config/impersonate.php:
'take_redirect_to' => 'dashboard',
'leave_redirect_to' => 'home',
Multi-Guard Support: Specify the guard when impersonating:
Auth::guard('admin')->user()->impersonate($targetUser);
Or in routes:
route('impersonate', ['id' => $id, 'guardName' => 'admin']);
Events:
Listen for impersonation events (e.g., in EventServiceProvider):
protected $listen = [
\EvoMark\Impersonate\Events\TakeImpersonation::class => [
\App\Listeners\LogImpersonation::class,
],
\EvoMark\Impersonate\Events\LeaveImpersonation::class => [
\App\Listeners\LogImpersonationEnd::class,
],
];
Middleware: Protect routes from impersonators:
Route::get('/admin', function () { ... })
->middleware('impersonate.protect');
Manual Impersonation:
Use the ImpersonateManager directly:
$manager = app('impersonate');
$manager->take(Auth::id(), $targetUserId); // Impersonate
$manager->leave(); // Leave
Session Key Conflicts:
impersonated_by as the session key by default. If you’re using other packages that modify the session (e.g., laravel-debugbar), ensure no conflicts arise.config/impersonate.php:
'session_key' => 'custom_impersonate_key',
Remember Me Token:
remember_token during impersonation. If you’re using custom auth logic (e.g., API tokens), ensure compatibility.remember() enabled:
Auth::user()->impersonate($targetUser)->remember();
Multi-Guard Quirks:
guardName is passed explicitly in routes or middleware.$manager->findUserById($id, 'admin'); // Throws exceptions for invalid providers
Blade Directive Scope:
@impersonating evaluate in the context of the current guard. If you switch guards dynamically, the directive may not reflect the correct state.@impersonating('admin')
Authorization Logic:
canImpersonate() or canBeImpersonated() return false, the impersonation will fail silently. Add logging or validation:
if (!Auth::user()->canImpersonate($targetUser)) {
throw new \Exception("Unauthorized to impersonate.");
}
Check Impersonation State:
Use the ImpersonateManager to debug:
$manager = app('impersonate');
dd($manager->isImpersonating(), $manager->getImpersonatorId());
Session Inspection: Inspect the session for impersonation data:
dd(session()->get('impersonated_by'));
Event Listeners: Add temporary logging to events for debugging:
TakeImpersonation::class => [\App\Listeners\DebugImpersonation::class],
Custom Strategies:
Extend the ImpersonateManager to add logic (e.g., audit logs):
$manager->take($from, $to);
event(new \App\Events\ImpersonationStarted($from, $to));
Blade Extensions:
Create custom directives by extending the package’s BladeServiceProvider:
Blade::if('customImpersonation', function ($user, $guard = null) {
return $user->canBeImpersonated() && !$user->isImpersonating($guard);
});
Middleware Logic:
Extend ImpersonateProtectMiddleware to add custom checks:
public function handle($request, Closure $next)
{
if (Auth::guard($this->guard)->user()->isImpersonating() && !$request->user()->is_admin) {
abort(403);
}
return $next($request);
}
Redirect Callables:
Use callables for dynamic redirects in config/impersonate.php:
'take_redirect_to' => function () {
return Auth::user()->preferredRedirect ?? '/';
},
Guard-Specific Config: The package supports per-guard configurations (advanced). Override the manager binding:
$app->bind('impersonate.admin', function ($app) {
return new \EvoMark\Impersonate\ImpersonateManager($app, 'admin');
});
Session Driver:
Ensure your session driver (e.g., database, redis) supports the session key. File-based sessions may cause issues in clustered environments.
How can I help you explore Laravel packages today?