Skip to content

OctopyID/LaraPersonate

Repository files navigation

Demo

Tests Version Downloads License

Laravel Impersonate

LaraPersonate is a lightweight, zero-dependency impersonation package for Laravel. Easily login as other users to troubleshoot issues or test features, either programmatically or via a beautifully crafted, plug-and-play UI widget.

✨ Highlights

  • Zero Dependencies: No jQuery, Select2, or Webpack. Just 100% Vanilla JS & CSS.
  • Plug & Play UI: A beautiful, responsive floating widget injected automatically.
  • Secure by Default: Built-in authorization guards to prevent unauthorized impersonation.
  • Performance Focused: Database-level search scoping (scopeImpersonatable) out of the box.
Impersonate Laravel Impersonate Laravel
v5.x 12.x - 13.x v2.x 7.x - 8.x
v4.x 10.x - 11.x v1.x 7.x - 8.x
v3.x 9.x - 10.x

Installation

Warning

This version is a breaking change, many changes were made to the addition of new features, new UI design, and code structure.

If you are upgrading from an old version, please republish the assets using the --force flag, configure and reset the limitations on the User Model according to this version.

To install the package, simply follow the steps below.

Install The Package

composer require octopyid/laravel-impersonate:^5

Publish The Package

php artisan vendor:publish --tag="impersonate" --force

Add HasImpersonation Trait to User Model

Add the trait Octopy\Impersonate\Concerns\HasImpersonation to your User model.

namespace App\Models;

use Octopy\Impersonate\Concerns\HasImpersonation;
use Illuminate\Foundation\Auth\User as Authenticatable;     

class User extends Authenticatable
{
    use HasImpersonation;
}

If you plan to use the provided UI, you can implement the Octopy\Impersonate\Contracts\HasImpersonationUI interface.

By default, the HasImpersonation trait already provides a sensible default for the UI configuration. It uses your name or email as the display text and allows searching via name or email.

However, you can easily override these defaults to fit your application by adding the methods to your User model:

namespace App\Models;

use Octopy\Impersonate\Concerns\HasImpersonation;
use Octopy\Impersonate\Contracts\HasImpersonationUI;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements HasImpersonationUI
{
    use HasImpersonation;
    
    /**
     * @return string
     */
    public function getImpersonateDisplayText() : string
    {
        // Override the default display text
        return $this->first_name . ' ' . $this->last_name;
    }
    
    /**
     * This following is useful for performing user searches through the interface,
     * You can use fields in relations freely using dot notation,
     * 
     * example: posts.title, department.name.   
     */
    public function getImpersonateSearchField() : array
    {
        // Override the default search fields
        return [
            'first_name', 'last_name', 'posts.title',
        ];
    }
}

Events

There are two events available that can be used to improve your workflow:

  • Octopy\Impersonate\Events\BeginImpersonation is fired when an impersonation is begin.
  • Octopy\Impersonate\Events\LeaveImpersonation is fired when an impersonation is leave.

Configuration

This configuration is intended to customize the appearance of Laravel Impersonate, if you don't need a UI and only want to use the backend logic, don't forget to set IMPERSONATE_UI_ENABLED to false in your environment file because it is enabled by default.

Please refer to the impersonate.php file to see the available configurations.

ENV Key Default Description
IMPERSONATE_UI_ENABLED true Enable or disable the impersonation UI widget
IMPERSONATE_UI_WIDTH 21rem Width of the UI widget panel
IMPERSONATE_UI_DEBOUNCE 300 Debounce delay (ms) before triggering the search request

Usage

Basic Usage

By default, you don't need to do anything, but keep in mind, Impersonation can be done by anyone if you don't define the rules of who can do impersonation or who can be impersonated.

Defining Limitation & Search Performance

To limit who can do impersonation or who is can be impersonated, implement the canImpersonate() and canBeImpersonated() methods on your User Model to enforce the limitation.

To improve the UI search performance and fix pagination accuracy, you should also utilize the Database Scope via scopeImpersonatable (or the modern #[Scope] attribute in Laravel 11+). This ensures that the search query only loads valid users directly from the database!

The example below uses Laratrust for role management where SUPER_ADMIN can perform impersonation against CUSTOMER.

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Attributes\Scope; // for Laravel 11+
use Illuminate\Foundation\Auth\User as Authenticatable;
use Octopy\Impersonate\Concerns\HasImpersonation;

class User extends Authenticatable
{
    use HasImpersonation;
    
    /**
     * DATABASE FILTER (For UI & Search Performance)
     * This limits the users retrieved for the UI dropdown.
     */
    #[Scope]
    public function impersonatable(Builder $query) : void
    {
        $query->whereHasRole('CUSTOMER');
    }

    /**
     * BACKEND AUTHORIZATION (For Core Security)
     * Validates if the authenticated user can impersonate.
     */
    public function canImpersonate() : bool
    {
        return $this->hasRole('SUPER_ADMIN');
    }

    /**
     * BACKEND AUTHORIZATION (For Core Security)
     * Validates if this user can be impersonated by others.
     */
    public function canBeImpersonated() : bool
    {
        return $this->hasRole('CUSTOMER');
    }
}

Warning Not defining the limitations in the Model or misdefining them can lead to serious security issues.

Advanced Usage

Impersonating User Manually

Sometimes you need Impersonating manually, to perform it, you can use the impersonate singleton.

impersonate()->begin($admin, $customer);

Or you can use the fluent loginAs() method which automatically uses the currently authenticated user as the impersonator:

impersonate()->loginAs($customer);

Or just simply call the impersonation method directly through the User Model.

$admin->impersonate($customer);

Defining Guard

Sometimes, you want to use custom guards for authentication, instead of the built-in guards.

impersonate()->guard('foo')->begin($admin, $customer);

Leaving Impersonation Mode

To leave Impersonation mode, you just need to call the leave method on impersonate singleton. This will return you to the original user.

impersonate()->leave();

Or via Model directly

$admin->impersonate()->leave();

Don't hesitate to use a guard if you need it.

Handling "Session Bleeding" (Security Warning)

When leaving impersonation (impersonate()->leave()), Laravel will regenerate the session ID. However, the existing session data is not cleared by default. If the impersonated user adds an item to a shopping cart (or triggers cached data) and the admin leaves the impersonation, the cart data will "bleed" back into the admin's session!

To prevent this, you should listen to the BeginImpersonation and LeaveImpersonation events and manually clear your application's specific sensitive session keys (e.g., cart_id, checkout_token).

Event::listen(function (LeaveImpersonation $event) {
    session()->forget('cart_id');
});

Disclaimer

This package can pose a serious security issue if used incorrectly, as anybody will be able to take control of any user's account.

By using this package, you agree that Octopy ID and the contributors of this package cannot be held responsible for any damages caused by using this package.

Security

If you discover any security-related issues, please email bug@octopy.dev instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Sponsor this project

  •  

Packages

 
 
 

Contributors