Web Analytics

mirror

⭐ 74 stars Spanish by franbarbalopez

Mirror Logo

Última Versión en Packagist Estado de Acciones de Pruebas en GitHub Descargas Totales Licencia

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

Requisitos

Instalación

composer require franbarbalopez/mirror
Opcional - publicar el archivo de configuración:

php artisan vendor:publish --tag=mirror

Inicio 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(): ?string

Alias

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:

Ambos eventos contienen al suplantador, al usuario objetivo y el nombre del guardia. Útil para registros de auditoría o para activar flujos de trabajo.

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)

@csrf
@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 ---