
Mirror
Mirror est un package d'usurpation d'utilisateur élégant pour Laravel. Il permet aux administrateurs de se connecter facilement en tant qu'autres utilisateurs pour résoudre des problèmes, fournir du support ou tester l'expérience utilisateur. Mirror gère l'intégrité des sessions avec une vérification cryptographique, une expiration automatique, un support multi-gardes, un middleware flexible et des événements de cycle de vie pour la journalisation d'audit. Parfait pour les applications en production nécessitant une usurpation d'utilisateur fiable et sécurisée.
Fonctionnalités
- Intégrité de session HMAC-SHA256 pour prévenir toute falsification
- Expiration TTL configurable
- Middleware pour le contrôle d'accès et l'application du TTL
- Support multi-gardes
- Redirection d'URL flexible
- Événements de cycle de vie pour la journalisation d'audit
Exigences
- PHP 8.2+
- Laravel 11+
Installation
composer require franbarbalopez/mirror
Optionnel - publier le fichier de configuration :php artisan vendor:publish --tag=mirrorDémarrage rapide
1. Ajouter un Trait au Modèle Utilisateur
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');
}
}
Important : Si vous n’implémentez pas canImpersonate(), tout le monde peut se faire passer pour n’importe qui. Le trait retourne true par défaut.
2. Commencer à usurper l’identité
use Mirror\Facades\Mirror;public function impersonate(User $user)
{
Mirror::start($user);
return redirect()->route('dashboard');
}
3. Cessez d'usurper l'identité
public function leave()
{
Mirror::stop(); return redirect()->route('admin.users.index');
}
Sécurité
Les sessions d'usurpation sont protégées par des hachages HMAC-SHA256 utilisant la clé de votre application. Le hachage couvre l'ID de l'usurpateur, le nom du garde, l'heure de début et l'URL de redirection. À chaque appel de stop(), Mirror vérifie ce hachage - si quelqu'un a altéré la session, il lance une exception et efface tout.
Configurez le TTL dans config/mirror.php pour expirer automatiquement les sessions après un temps défini.
Référence API
Démarrer une usurpation
Par instance utilisateur :
Mirror::start($user);// With redirect URLs
$redirectUrl = Mirror::start(
user: $targetUser,
leaveRedirectUrl: route('admin.users.index'),
startRedirectUrl: route('dashboard')
);
return redirect($redirectUrl);
Par clé primaire (fonctionne avec int, UUID, ULID, etc.) :
Mirror::startByKey(123);Mirror::startByKey('550e8400-e29b-41d4-a716-446655440000');
Par courriel :Mirror::startByEmail('user@example.com');Arrêt de l'usurpation d'identité
Mirror::stop();// Force stop - bypasses TTL check but still verifies integrity
Mirror::forceStop();
Utilisez forceStop() lorsque vous devez mettre fin à l'usurpation depuis des actions d'administration ou des scripts de nettoyage - cela ignore la vérification TTL mais génère toujours une erreur si la session a été altérée.
Vérification de l'état
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
Vérifie si la session d'usurpation a expiré et appelle automatiquement stop() si nécessaire :
Route::middleware('mirror.ttl')->group(function () {
Route::get('/admin/users', [UserController::class, 'index']);
Route::get('/admin/users/{user}', [UserController::class, 'show']);
});Utile pour protéger les zones d'administration sensibles où vous souhaitez que les sessions expirées se terminent proprement. Notez que lorsque le TTL expire, ce middleware met fin à l'usurpation d'identité et redirige, assurez-vous donc que le nettoyage de votre session est correctement configuré.
mirror.require
N'autorise l'accès que si une usurpation d'identité est active :
Route::middleware('mirror.require')->group(function () {
Route::get('/impersonation/banner', function () {
return view('impersonation.banner');
});
});
Utile pour les composants UI spéciaux qui n'ont de sens que lors de l'usurpation d'identité - comme une bannière indiquant qui vous usurpez.mirror.prevent
Bloque l'accès pendant l'usurpation d'identité :
Route::middleware('mirror.prevent')->group(function () {
Route::post('/admin/users/{user}/delete', [UserController::class, 'destroy']);
Route::get('/admin/settings', [SettingsController::class, 'edit']);
});Protège les actions destructrices ou les paramètres sensibles qui ne doivent être accessibles qu'en tant qu'utilisateur original, et non lors de l'usurpation d'identité d'une autre personne.
Autorisation
Le trait Impersonatable fournit deux méthodes qui retournent toutes deux true par défaut. Surchargez-les pour ajouter votre propre logique :
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');
}
}
Vous n'avez pas besoin du trait - Mirror recherchera ces méthodes sur votre modèle utilisateur quoi qu'il arrive :
class User extends Authenticatable
{
public function canImpersonate(): bool
{
return $this->hasPermission('impersonate-users');
} public function canBeImpersonated(): bool
{
return ! $this->is_system_account;
}
}
Redirection d’URL
Vous pouvez contrôler où les utilisateurs vont lorsqu’ils commencent et arrêtent l’usurpation d’identité :
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 vous ne spécifiez pas leaveRedirectUrl, il prend par défaut l'URL actuelle où start() a été appelé.
Événements
Mirror déclenche deux événements auxquels vous pouvez vous abonner :
Mirror\Events\ImpersonationStartedMirror\Events\ImpersonationStopped
Les événements sont déclenchés après que la réponse a été envoyée au client, garantissant que les opérations critiques d'usurpation se terminent sans délai. Ceci est particulièrement important pour les middlewares comme mirror.ttl qui peuvent s'exécuter à chaque requête.
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,
]);
});
Performance et optimisation
Mirror est optimisé pour les applications à haute performance :
Mise en cache à l’échelle de la requête
Le modèle d’usurpation est mis en cache au sein d’une seule requête pour éviter les requêtes redondantes à la base de données :
// 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();
Cela est particulièrement bénéfique pour les middlewares comme mirror.ttl qui s'exécutent à chaque requête.
Diffusion différée des événements
Les événements d'usurpation d'identité sont diffusés après l'envoi de la réponse au client, garantissant que les écouteurs d'événements n'impactent pas le temps de réponse. Cela maintient votre cycle de requête rapide tout en permettant la journalisation d'audit et d'autres tâches en arrière-plan.
Support Multi-Guard
Mirror détecte automatiquement quel garde vous utilisez :
Auth::guard('admin')->login($admin);Mirror::start($user); // uses 'admin' guard
Mirror::stop(); // restores to 'admin' guard
Vous n'avez pas besoin de spécifier manuellement le garde - il le déduit du contexte d'authentification actuel.
Directives Blade
@impersonating
@impersonating
You're impersonating {{ auth()->user()->name }}.
Exit
@endimpersonating{{-- Check specific guard --}}
@impersonating('admin')
Impersonating via admin guard
@endimpersonating@peuxJeUsurper
@canImpersonate
Manage Users
@endcanImpersonate{{-- With guard --}}
@canImpersonate('admin')
Admin tools
@endcanImpersonate@peutÊtreUsurpé
{{-- Check current user --}}
@canBeImpersonated
Available for support
@endcanBeImpersonated{{-- Check specific user --}}
@canBeImpersonated($user)
@endcanBeImpersonated{{-- With guard --}}
@canBeImpersonated($user, 'admin')
@endcanBeImpersonated
Licence
MIT. Voir LICENSE.md.
Crédits
Développé par franbarbalopez.
--- Tranlated By Open Ai Tx | Last indexed: 2025-12-07 ---