octopyid/laravel-impersonate
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
--forceflag, 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\BeginImpersonationis fired when an impersonation is begin.Octopy\Impersonate\Events\LeaveImpersonationis 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.