Filament Impersonate

repository·master·Indexed 18 days ago

https://github.com/stechstudio/filament-impersonate

A plugin for the Filament PHP framework that allows administrators to impersonate other users for debugging or viewing the application from a specific user's perspective. It provides an Impersonate action for Filament tables and pages, a customizable impersonation banner, and an Impersonation facade for programmatic control over sessions.

Tokens
3.8K
Snippets
20
Records
21
Agent score
61%

What's inside filament-impersonate

  1. Restrict Impersonation permissions on the User model

    master

    You can control who can impersonate and who can be impersonated by adding specific methods to your User model:

    1. canImpersonate(): Determines if the current authenticated user has permission to start an impersonation session.
    2. canBeImpersonated(): Determines if a specific target user is allowed to be impersonated.
    class User {
    
        public function canImpersonate()
        {
            return $this->is_admin;
        }
    
        public function canBeImpersonated()
        {
            return !str_ends_with($this->email, '@mycorp.com');
        }
        
    }
  2. Display the Impersonation Banner in non-Filament layouts

    master

    If your application has pages outside of the Filament panel, you must manually add the impersonation banner to your master layout to allow users to exit the impersonation session.

    Place the <x-impersonate::banner/> component inside your layout, typically just before the closing </body> tag.

    <x-impersonate::banner/>
  3. Add the Impersonate action to a Filament Page

    master

    To add an impersonate button to a specific page (like an EditRecord page), add the Impersonate action to the getHeaderActions method.

    Important: You must pass the record to the action using ->record($this->getRecord()) so the plugin knows which user to impersonate.

    <?php
    namespace App\Filament\Resources\UserResource\Pages;
    
    use App\Filament\Resources\UserResource;
    use Filament\Resources\Pages\EditRecord;
    use STS\FilamentImpersonate\Actions\Impersonate;
    
    class EditUser extends EditRecord
    {
        protected static string $resource = UserResource::class;
    
        protected function getHeaderActions(): array
        {
            return [
                Impersonate::make()->record($this->getRecord()), // <--
            ];
        }
    }
  4. Add the Impersonate action to a Filament Table

    master

    To allow impersonation from a list view, add the STS\FilamentImpersonate\Actions\Impersonate action to your Resource's table method.

    You can customize the behavior using:

    • ->guard('guard-name'): Specify a different authentication guard.
    • ->redirectTo(route('name')): Define where the user should be redirected after impersonation starts.
    • ->withoutSpa(): If your panel uses SPA mode, use this to force a full page load if the redirect target is not Livewire-aware.
    namespace App\Filament\Resources;
    
    use Filament\Resources\Resource;
    use STS\FilamentImpersonate\Actions\Impersonate;
    
    class UserResource extends Resource {
        public static function table(Table $table)
        {
            return $table
                ->columns([
                    // ...
                ])
                ->actions([
                    Impersonate::make(), // <--- 
                ]);
        }
    }
  5. Fix 403 errors in User Policies during impersonation

    master

    If you encounter a 403 Forbidden error when using a ListUsers widget with InteractsWithPageTable, it is likely because the impersonated user lacks permission to view the user list, causing Livewire to fail during re-renders.

    To resolve this, update your Policy (e.g., UserPolicy::viewAny()) to allow access if the current user is actively impersonating someone.

    use STS\FilamentImpersonate\Facades\Impersonation;
    
    public function viewAny(User $user): bool
    {
        if (Impersonation::isImpersonating()) {
            return true;
        }
    
        // ... existing logic
    }
  6. Use the Impersonation Facade for programmatic control

    master

    Use the STS\FilamentImpersonate\Facades\Impersonation facade to check impersonation status or to force a user to leave the impersonation session.

    use STS\FilamentImpersonate\Facades\Impersonation;
    
    if (Impersonation::isImpersonating()) {
        Impersonation::leave();
    }
  7. Customize the Impersonation Banner

    master

    The <x-impersonate::banner/> Blade component supports customization:

    • style: Set the visual theme. Options are 'light', 'dark' (default), or 'auto'.
    • :display: Override the name shown in the banner (e.g., using an email instead of a name attribute).
    <!-- Light style banner -->
    <x-impersonate::banner style='light'/>
    
    <!-- Banner showing email instead of name -->
    <x-impersonate::banner :display='auth()->user()->email'/>
  8. Configure the impersonation banner render hook

    master

    By default, the impersonation banner is rendered via a Filament render hook at panels::body.start. You can customize which Filament render hook is used to display the banner by modifying the banner.render_hook key in your config/filament-impersonate.php configuration file.

    // In config/filament-impersonate.php
    'banner' => [
        'render_hook' => 'panels::body.start', // Change this to another Filament render hook
    ],
  9. Enter impersonation mode

    master

    The enter() method transitions the session from the current user ($from) to a target user ($to).

    Parameters:

    • Authenticatable $from: The user currently logged in (the impersonator).
    • Authenticatable $to: The user to be impersonated.
    • ?string $guardName: (Optional) The name of the guard to use for the target user.

    Behavior:

    • It saves the current authentication cookie in the session to preserve 'remember me' functionality.
    • It updates the session with the impersonator's ID and guard information.
    • It clears the current user from the session and sets the target user.
    • It fires the EnterImpersonation event.
    • Returns true on success, or false if an error occurs (in which case it calls clear() to clean up the session).
    // Example: Admin (user A) impersonating Customer (user B)
    $impersonateManager->enter($adminUser, $customerUser, 'web');