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.
- 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 |
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
--forceflag, configure and reset the limitations on the User Model according to this version.
To install the package, simply follow the steps below.
composer require octopyid/laravel-impersonate:^5php artisan vendor:publish --tag="impersonate" --forceAdd 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',
];
}
}There are two events available that can be used to improve your workflow:
Octopy\Impersonate\Events\BeginImpersonationis fired when an impersonation is begin.Octopy\Impersonate\Events\LeaveImpersonationis fired when an impersonation is leave.
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 |
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.
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.
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);Sometimes, you want to use custom guards for authentication, instead of the built-in guards.
impersonate()->guard('foo')->begin($admin, $customer);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.
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');
});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.
If you discover any security-related issues, please email bug@octopy.dev instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
