
Mirror
Mirror es un paquete elegante de suplantación de usuario para Laravel. Permite a los administradores iniciar sesión como otros usuarios sin problemas para solucionar problemas, brindar soporte o probar experiencias de usuario. Mirror maneja la integridad de la sesión con verificación criptográfica, expiración automática, soporte multi-guard, middleware flexible y eventos de ciclo de vida para el registro de auditoría. Perfecto para aplicaciones en producción que necesitan una suplantación de usuario confiable y segura.
Características
- Integridad de sesión HMAC-SHA256 para prevenir manipulaciones
- Expiración TTL configurable
- Middleware para control de acceso y aplicación de TTL
- Soporte multi-guard
- Redirección de URL flexible
- Eventos de ciclo de vida para registro de auditoría
Requisitos
- PHP 8.2+
- Laravel 11+
Instalación
composer require franbarbalopez/mirror
Opcional - publicar el archivo de configuración:php artisan vendor:publish --tag=mirrorInicio Rápido
1. Agregar Trait al Modelo de Usuario
use Illuminate\Foundation\Auth\User as Authenticatable;
use Mirror\Concerns\Impersonatable;class User extends Authenticatable
{
use Impersonatable;
public function canImpersonate(): bool
{
return $this->hasRole('admin');
}
public function canBeImpersonated(): bool
{
return ! $this->hasRole('super-admin');
}
}
Importante: Si no implementas canImpersonate(), todos pueden suplantar a todos. El trait devuelve true por defecto.
2. Comenzar a suplantar
use Mirror\Facades\Mirror;public function impersonate(User $user)
{
Mirror::start($user);
return redirect()->route('dashboard');
}
3. Deja de suplantar identidad
public function leave()
{
Mirror::stop(); return redirect()->route('admin.users.index');
}
Seguridad
Las sesiones de suplantación están protegidas con hashes HMAC-SHA256 usando la clave de tu aplicación. El hash cubre el ID del suplantador, el nombre del guardia, la hora de inicio y la URL de redirección. En cada llamada a stop(), Mirror verifica este hash; si alguien ha manipulado la sesión, lanza una excepción y borra todo.
Configura el TTL en config/mirror.php para que las sesiones expiren automáticamente después de un tiempo establecido.
Referencia de la API
Iniciar Suplantación
Por instancia de usuario:
Mirror::start($user);// With redirect URLs
$redirectUrl = Mirror::start(
user: $targetUser,
leaveRedirectUrl: route('admin.users.index'),
startRedirectUrl: route('dashboard')
);
return redirect($redirectUrl);
Por clave primaria (funciona con int, UUID, ULID, etc.):
Mirror::startByKey(123);Mirror::startByKey('550e8400-e29b-41d4-a716-446655440000');
Por correo electrónico:
Mirror::startByEmail('user@example.com');Detener la suplantación
Mirror::stop();// Force stop - bypasses TTL check but still verifies integrity
Mirror::forceStop();
Use forceStop() cuando necesite terminar la suplantación desde acciones de administrador o scripts de limpieza - omite la verificación de TTL pero aún lanza un error si la sesión ha sido manipulada.
Comprobación del estado
Mirror::isImpersonating(): bool
Mirror::getImpersonator(): ?Authenticatable
Mirror::impersonatorId(): int|string|null
Mirror::getLeaveRedirectUrl(): ?stringAlias
Mirror::as($user); // same as start()
Mirror::leave(); // same as stop()
Mirror::impersonating(); // same as isImpersonating()
Mirror::impersonator(); // same as getImpersonator()Middleware
mirror.ttl
Comprueba si la sesión de suplantación ha expirado y llama automáticamente a stop() si es necesario:
Route::middleware('mirror.ttl')->group(function () {
Route::get('/admin/users', [UserController::class, 'index']);
Route::get('/admin/users/{user}', [UserController::class, 'show']);
});Bueno para proteger áreas administrativas sensibles donde deseas que las sesiones expiradas terminen de manera elegante. Ten en cuenta que cuando el TTL expira, este middleware finalizará la suplantación y redirigirá, así que asegúrate de que la limpieza de tu sesión esté configurada correctamente.
mirror.require
Solo permite el acceso si se está suplantando activamente:
Route::middleware('mirror.require')->group(function () {
Route::get('/impersonation/banner', function () {
return view('impersonation.banner');
});
});Útil para componentes de UI especiales que solo tienen sentido durante la suplantación, como un banner que muestra a quién estás suplantando.
mirror.prevent
Bloquea el acceso mientras se está suplantando:
Route::middleware('mirror.prevent')->group(function () {
Route::post('/admin/users/{user}/delete', [UserController::class, 'destroy']);
Route::get('/admin/settings', [SettingsController::class, 'edit']);
});Protege acciones destructivas o configuraciones sensibles que solo deben ser accesibles como el usuario original, no mientras se está suplantando a otra persona.
Autorización
El trait Impersonatable proporciona dos métodos que ambos retornan true por defecto. Sobrescríbelos para agregar tu propia lógica:
use Mirror\Concerns\Impersonatable;class User extends Authenticatable
{
use Impersonatable;
public function canImpersonate(): bool
{
return $this->hasRole('admin');
}
public function canBeImpersonated(): bool
{
return ! $this->hasRole('super-admin');
}
}
No necesitas el trait: Mirror buscará estos métodos en tu modelo de usuario independientemente:
class User extends Authenticatable
{
public function canImpersonate(): bool
{
return $this->hasPermission('impersonate-users');
} public function canBeImpersonated(): bool
{
return ! $this->is_system_account;
}
}
Redirección de URL
Puedes controlar a dónde van los usuarios al iniciar y detener la suplantación:
public function impersonate(User $user)
{
$redirectUrl = Mirror::start(
user: $user,
leaveRedirectUrl: route('admin.users.index'), // where to go when they stop
startRedirectUrl: route('dashboard') // where to go right now
); return redirect($redirectUrl);
}
public function leave()
{
Mirror::stop();
return redirect(Mirror::getLeaveRedirectUrl());
}
Si no especificas leaveRedirectUrl, se usará por defecto la URL actual donde se llamó a start().Eventos
Mirror envía dos eventos a los que puedes suscribirte:
Mirror\Events\ImpersonationStartedMirror\Events\ImpersonationStopped
Los eventos se envían después de que la respuesta se envía al cliente, asegurando que las operaciones críticas de suplantación se completen sin demora. Esto es especialmente importante para middleware como mirror.ttl que puede ejecutarse en cada solicitud.
use Mirror\Events\ImpersonationStarted;Event::listen(ImpersonationStarted::class, function (ImpersonationStarted $event) {
// Log the activity to your audit system of choice
Log::info('User impersonation started', [
'impersonator_id' => $event->impersonator->id,
'impersonated_id' => $event->impersonated->id,
'guard' => $event->guardName,
]);
});
Rendimiento y Optimización
Mirror está optimizado para aplicaciones de alto rendimiento:
Caché con Ámbito de Solicitud
El modelo de suplantación se almacena en caché dentro de una única solicitud para evitar consultas redundantes a la base de datos:
// This first call will query the database
$impersonator = Mirror::getImpersonator();// Subsequent calls in the same request use the cached instance, therefore this one will not:
$impersonator = Mirror::getImpersonator();
Esto es particularmente beneficioso para middleware como mirror.ttl que se ejecutan en cada solicitud.
Despacho Diferido de Eventos
Los eventos de suplantación se despachan después de que la respuesta se envía al cliente, asegurando que los escuchas de eventos no afecten el tiempo de respuesta. Esto mantiene rápido tu ciclo de solicitud mientras permite el registro de auditorías y otras tareas en segundo plano.
Soporte Multi-Guard
Mirror detecta automáticamente qué guardia estás usando:
Auth::guard('admin')->login($admin);Mirror::start($user); // uses 'admin' guard
Mirror::stop(); // restores to 'admin' guard
No necesitas especificar el guard manualmente: lo determina a partir del contexto de autenticación actual.
Directivas de Blade
@impersonating
@impersonating
You're impersonating {{ auth()->user()->name }}.
Exit
@endimpersonating{{-- Check specific guard --}}
@impersonating('admin')
Impersonating via admin guard
@endimpersonating@puedoPersonificar
@canImpersonate
Manage Users
@endcanImpersonate{{-- With guard --}}
@canImpersonate('admin')
Admin tools
@endcanImpersonate@puedeSerSuplantado
{{-- Check current user --}}
@canBeImpersonated
Available for support
@endcanBeImpersonated{{-- Check specific user --}}
@canBeImpersonated($user)
@endcanBeImpersonated{{-- With guard --}}
@canBeImpersonated($user, 'admin')
@endcanBeImpersonated
Licencia
MIT. Ver LICENSE.md.
Créditos
Desarrollado por franbarbalopez.
--- Tranlated By Open Ai Tx | Last indexed: 2025-12-07 ---