Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Impersonate Laravel Package

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+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require evo-mark/laravel-impersonate
    
  2. Add the service provider to config/app.php:
    'providers' => [
        // ...
        EvoMark\Impersonate\ImpersonateServiceProvider::class,
    ],
    
  3. Add the trait to your User model:
    use EvoMark\Impersonate\Models\Impersonate;
    
    class User extends Authenticatable
    {
        use Impersonate;
        // ...
    }
    

First Use Case: Impersonating a User

  • Impersonate a user (e.g., in a controller or Tinker):
    Auth::user()->impersonate($otherUser);
    
  • Leave impersonation:
    Auth::user()->leaveImpersonation();
    

Quick UI Integration

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

Implementation Patterns

Core Workflow

  1. Impersonation Logic:

    • Use the impersonate() method on the authenticated user:
      Auth::user()->impersonate($targetUser);
      
    • Leave impersonation with:
      Auth::user()->leaveImpersonation();
      
    • Check if impersonating:
      if (Auth::user()->isImpersonating()) { ... }
      
  2. Authorization:

    • Override canImpersonate() in your User model to restrict who can impersonate:
      public function canImpersonate()
      {
          return $this->is_admin;
      }
      
    • Override canBeImpersonated() to restrict who can be impersonated:
      public function canBeImpersonated()
      {
          return $this->is_impersonatable;
      }
      
  3. Blade Directives:

    • Show impersonation links conditionally:
      @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
      

Advanced Patterns

  1. 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',
    
  2. Multi-Guard Support: Specify the guard when impersonating:

    Auth::guard('admin')->user()->impersonate($targetUser);
    

    Or in routes:

    route('impersonate', ['id' => $id, 'guardName' => 'admin']);
    
  3. 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,
        ],
    ];
    
  4. Middleware: Protect routes from impersonators:

    Route::get('/admin', function () { ... })
         ->middleware('impersonate.protect');
    
  5. Manual Impersonation: Use the ImpersonateManager directly:

    $manager = app('impersonate');
    $manager->take(Auth::id(), $targetUserId); // Impersonate
    $manager->leave(); // Leave
    

Gotchas and Tips

Pitfalls

  1. Session Key Conflicts:

    • The package uses 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.
    • Fix: Customize the session key in config/impersonate.php:
      'session_key' => 'custom_impersonate_key',
      
  2. Remember Me Token:

    • The package preserves the remember_token during impersonation. If you’re using custom auth logic (e.g., API tokens), ensure compatibility.
    • Tip: Test with remember() enabled:
      Auth::user()->impersonate($targetUser)->remember();
      
  3. Multi-Guard Quirks:

    • When using multiple guards, ensure the guardName is passed explicitly in routes or middleware.
    • Debugging: Check if the guard’s user provider is valid:
      $manager->findUserById($id, 'admin'); // Throws exceptions for invalid providers
      
  4. Blade Directive Scope:

    • Blade directives like @impersonating evaluate in the context of the current guard. If you switch guards dynamically, the directive may not reflect the correct state.
    • Workaround: Pass the guard name explicitly:
      @impersonating('admin')
      
  5. Authorization Logic:

    • If 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.");
      }
      

Debugging Tips

  1. Check Impersonation State: Use the ImpersonateManager to debug:

    $manager = app('impersonate');
    dd($manager->isImpersonating(), $manager->getImpersonatorId());
    
  2. Session Inspection: Inspect the session for impersonation data:

    dd(session()->get('impersonated_by'));
    
  3. Event Listeners: Add temporary logging to events for debugging:

    TakeImpersonation::class => [\App\Listeners\DebugImpersonation::class],
    

Extension Points

  1. Custom Strategies: Extend the ImpersonateManager to add logic (e.g., audit logs):

    $manager->take($from, $to);
    event(new \App\Events\ImpersonationStarted($from, $to));
    
  2. Blade Extensions: Create custom directives by extending the package’s BladeServiceProvider:

    Blade::if('customImpersonation', function ($user, $guard = null) {
        return $user->canBeImpersonated() && !$user->isImpersonating($guard);
    });
    
  3. 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);
    }
    

Configuration Quirks

  1. Redirect Callables: Use callables for dynamic redirects in config/impersonate.php:

    'take_redirect_to' => function () {
        return Auth::user()->preferredRedirect ?? '/';
    },
    
  2. 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');
    });
    
  3. Session Driver: Ensure your session driver (e.g., database, redis) supports the session key. File-based sessions may cause issues in clustered environments.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony