verseles/possession
Laravel Possession - User Impersonation Package
A simple user impersonation package for Laravel with Sanctum compatibility.
Features
- Secure user impersonation system
- Global
possess()andunpossess()methods - Comprehensive exception handling
- Session-based impersonation
- Sanctum compatibility
- Simple administration controls
- Visual impersonation indicator
- Easy to integrate
It wasn't tested with all Laravel versions, only with Laravel 11 and 12.
Installation
- Install via Composer:
composer require verseles/possession
- Publish the configuration file (optional):
php artisan vendor:publish --tag=possession-config
- Add the trait to your User model:
use Verseles\Possession\Traits\ImpersonatesUsers;
class User extends Authenticatable
{
use ImpersonatesUsers;
// Add your possession logic
public function canPossess()
{
return $this->is_admin; // Your admin check logic
}
public function canBePossessed()
{
return !$this->is_admin; // Example restriction
}
}
Usage
Global Methods
Use the facade for direct impersonation control:
use Verseles\Possession\Facades\Possession;
// Possess a user (accepts ID, email, or User model instance)
try {
Possession::possess($targetUser);
} catch (\Verseles\Possession\Exceptions\ImpersonationException $e) {
// Handle exception
return redirect()->back()->withErrors(['impersonation' => $e->getMessage()]);
}
// Stop possessing
try {
Possession::unpossess();
} catch (\Verseles\Possession\Exceptions\ImpersonationException $e) {
// Handle exception
return redirect()->back()->withErrors(['impersonation' => $e->getMessage()]);
}
Web Routes Example
// routes/web.php
use Verseles\Possession\Facades\Possession;
Route::middleware(['web', 'auth:'.config('possession.admin_guard')])->group(function () {
Route::post('/possession/impersonate/{user}', function ($user) {
try {
Possession::possess($user);
return redirect()->route('dashboard');
} catch (\Verseles\Possession\Exceptions\ImpersonationException $e) {
return back()->withErrors(['impersonation' => $e->getMessage()]);
}
});
Route::post('/possession/leave', function () {
try {
Possession::unpossess();
return redirect()->route('admin.dashboard');
} catch (\Verseles\Possession\Exceptions\ImpersonationException $e) {
return back()->withErrors(['impersonation' => $e->getMessage()]);
}
});
});
Blade Templates
Start Impersonation:
@if(auth()->check() && auth()->user()->canImpersonate())
<form action="{{ route('possession.impersonate', $user->id) }}" method="POST">
@csrf
<button type="submit">Impersonate User</button>
</form>
@endif
Stop Impersonation:
@include('possession::impersonating')
Error Handling
The package throws specific exceptions you can catch:
use Verseles\Possession\Exceptions\ImpersonationException;
try {
Possession::possess($user);
} catch (ImpersonationException $e) {
// Handle specific error types:
if ($e->getCode() === 403) {
// Authorization error
}
// General error handling
return back()->withErrors(['impersonation' => $e->getMessage()]);
}
Available exceptions:
UnauthorizedPossessExceptionUnauthorizedUnpossessExceptionTargetCannotBePossessedExceptionSelfPossessionExceptionNoImpersonationActiveExceptionAlreadyImpersonatingExceptionAdminNotFoundException— original admin not found during unpossess (e.g., deleted)
Configuration
Edit config/possession.php after publishing:
return [
'user_model' => App\Models\User::class,
'admin_guard' => 'web',
'session_keys' => [
'original_user' => 'possession.original_user_id',
],
];
Security Considerations
- Always protect impersonation routes with middleware
- Use separate guards for admin and regular users
- Regularly review your
canPossess()andcanBePossessed()logic - Never expose impersonation controls to non-administrative users
License
The MIT License (MIT)
Related Packages
doctrine/dbal
Powerful PHP database abstraction layer (DBAL) with many features for database s...
634,760,849
9,707
laravel/serializable-closure
Laravel Serializable Closure provides an easy and secure way to serialize closur...
408,553,772
609
nunomaduro/collision
Cli error handling for console/command-line PHP applications.
387,976,821
4,658