About Me
Мy name is Dzianis Kotau. I'm Solutions Architect and Zend Certified PHP Engineer. I'm PHP evangelist and loved in it.
MoonShine Impersonate v3
MoonShine Impersonate предоставляет возможность подмены пользователя в проектах на Laravel с использованием админ-панели MoonShine. Функциональность подмены пользователя позволяет админстратору войти на сайт как реальный пользователь. Это может быть полезно, чтобы посмотреть, как сайт виден обычному пользователю, воспроизвести баги от его имени и т.д.
Содержимое
Установка
MoonShine Impersonate спроектирован для использования в составе админ-панели MoonShine. Поэтому, сперва установите админ-панель, следуя инструкциям с официального сайте MoonShine. Затем установите данный пакет при помощи команды:
composer require jampire/moonshine-impersonate
Обновление
- Минимальная поддерживаемая версия PHP - 8.2.
- Минимальная поддерживаемая версия MoonShine - 4.0.
- Ранее ключ
redirect_toбыл строкой. Теперь же это массив, состоящий из двух элементов:redirect_to.enterиredirect_to.stop. - Компонент
StopImpersonationи все его ресурсы удалены. Используйте кнопку действияStopImpersonationActionButton. - Метод
ImpersonateManager.getUserFromSession()больше не выбрасывает исключений в случае ошибок, а возвращаетnull. - Все классы пакета теперь финализированы.
Настройка
MoonShine Impersonate способен работать из коробки с настройками по умолчанию. Но вы можете опубликовать его
настройки в свою директорию config и изменть нужные пареметры (зачастую в файле .env):
php artisan vendor:publish --provider="Jampire\MoonshineImpersonate\ImpersonateServiceProvider" --tag=config
Также можно опубликовать файлы локализации для более тонкой настройки:
php artisan vendor:publish --provider="Jampire\MoonshineImpersonate\ImpersonateServiceProvider" --tag=lang
Использование
Базовое использование
Включение подмены пользователя
Т.к. данный пакет работает с системой авторизации, то применять его можно на модели User. Для этого создайте
MoonShine ресурс, использующий модель авторизации User вашего приложения.
После создания MoonShine ресурса User, откройте файл app/MoonShine/Resources/User/Pages/UserIndexPage.php,
который может выглядеть так:
<?php
declare(strict_types=1);
namespace App\MoonShine\Resources\User\Pages;
use MoonShine\Laravel\Pages\Crud\IndexPage;
use MoonShine\Contracts\UI\FieldContract;
use MoonShine\UI\Fields\Email;
use MoonShine\UI\Fields\ID;
use App\MoonShine\Resources\User\UserResource;
use MoonShine\Support\ListOf;
use MoonShine\UI\Fields\Text;
class UserIndexPage extends IndexPage
{
protected bool $isLazy = true;
protected function fields(): iterable
{
return [
ID::make(),
Text::make('Name'),
Email::make('E-mail', 'email'),
];
}
protected function buttons(): ListOf
{
return parent::buttons();
}
// ...
}
Для добавления действия подмены пользователя пакет MoonShine Impersonate предоставляет свою кнопку действия
EnterImpersonationActionButton. Для его добавления воспользуйтесь методом buttons() класса UserIndexPage:
<?php
declare(strict_types=1);
namespace App\MoonShine\Resources\User\Pages;
use Jampire\MoonshineImpersonate\UI\ActionButtons\EnterImpersonationActionButton;
use MoonShine\Contracts\UI\ActionButtonContract;
use MoonShine\Laravel\Pages\Crud\IndexPage;
use App\MoonShine\Resources\User\UserResource;
use MoonShine\Support\ListOf;
// ...
class UserIndexPage extends IndexPage
{
// ...
protected function buttons(): ListOf
{
return parent::buttons()
->prepend(EnterImpersonationActionButton::resolve());
}
// ...
}
За тонкую настройку этого действия отвечают секция buttons.enter файла конфигурации и секция ui.buttons.enter
файлов локализации.
После подключения данного действия ваш ресурс Users может выглядеть следующим образом:

При нажатии на эту кнопку вы переключитесь на выбранного пользователя (Livewire Starter Kit):

Отключение подмены пользователя
Для отключения действия подмены пользователя пакет MoonShine Impersonate предоставляет свою кнопку действия
StopImpersonationActionButton. Рассмотрим способ размещения кнопки отключения в заголовке шаблона. Разместив
кнопку в заголовке, вы всегда будите знать, что находитесь в режиме подмены пользователя, т.к. кнопка будет видна на
всех страницах админ-панели (когда режим подмены остановлен, кнопка видна не будет).
Для того, чтобы размещать кастомные элементы в заголовке шаблона, вам нужно отредактировать шаблон
app/MoonShine/Layouts/MoonShineLayout.php. Для примера, разместим кнопку как предпоследний элемент:
<?php
declare(strict_types=1);
namespace App\MoonShine\Layouts;
use Jampire\MoonshineImpersonate\UI\ActionButtons\StopImpersonationActionButton;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\UI\Components\Layout\Header;
// ...
final class MoonShineLayout extends AppLayout
{
// ...
#[\Override]
protected function getHeaderComponent(): Header
{
$stopImpersonation = StopImpersonationActionButton::resolve();
$components = parent::getHeaderComponent()->getComponents();
$components->splice($components->count() - 2, 0, [$stopImpersonation]);
return Header::make($components);
}
}

Middleware
Для своей работы режим подмены пользователя использует ImpersonateMiddleware класс. По-умолчанию он работает с
маршрутами (routes) в группе web. Если вы хотите добавить этот middleware к другим маршрутам, воспольуйтесь
псевдонимом impersonate. Например, его можно подключить в контроллере:
class PostController extends Controller
{
public function __construct()
{
$this->middleware('impersonate');
}
}
Разрешения
По умолчанию, любой администратор может подменять любого пользователя. Если вы желаете более тонкую настройку
разрешений (permissions), можно воспользоваться интерфейсами Impersonable и BeImpersonable и реализовать методы
canImpersonate() и canBeImpersonated() соответственно.
Рассмотрим один из способов ограничения прав админа через его модель. Для этого, создадим модель Admin,
унаследовавшись от MoonShine\Permissions\Models\MoonshineUser и реализовав метод canImpersonate():
<?php
namespace App\Models;
use Jampire\MoonshineImpersonate\Services\Contracts\Impersonable;
use MoonShine\Laravel\Models\MoonshineUser;
use MoonShine\Laravel\Models\MoonshineUserRole;
final class Admin extends MoonshineUser implements Impersonable
{
public function getTable(): string
{
return (new parent())->getTable();
}
public function canImpersonate(): bool
{
return $this->moonshine_user_role_id === MoonshineUserRole::DEFAULT_ROLE_ID;
}
}
После чего нужно указать в файле конфигурации config/moonshine.php, что мы хотим использовать модель Admin
вместо MoonshineUser:
return [
// Authentication and profile
'auth' => [
// ...
'model' => \App\Models\Admin::class,
// ...
],
];
А чтобы контролировать, кого из пользователей можно подменять, нужно реализовать метод canBeImpersonated()
на моделе авторизации User:
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Str;
use Jampire\MoonshineImpersonate\Services\Contracts\BeImpersonable;
final class User extends Authenticatable implements BeImpersonable
{
// ...
public function canBeImpersonated(): bool
{
return !Str::endsWith($this->email, '@verysecureemail.com');
}
}
Запись событий (логирование)
Если вы желаете, то можете включить запись событий переключения пользователя в журнал MoonShine (по-умолчанию
отключено). Для включение режима записи вам необходимо установить пакет MoonShine Changelog и добавить
трейт HasChangeLog к модели авторизации User (не забудьте настроить и запустить очередь событий):
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use MoonShine\ChangeLog\Traits\HasChangeLog;
final class User extends Authenticatable
{
use HasChangeLog;
// ...
}
При старте режима подмены пользователя в журнале (таблица moonshine_change_logs) появится следующая запись:
id: 7
moonshine_user_id: 1 # пользователь, который запустил режим подмены (админ)
changelogable_type: App\Models\User # модель авторизации пользователя
changelogable_id: 4 # пользователь, которого подменяют
states_before: "impersonation_stopped" # статус приложения до начала подмены
states_after: "impersonation_entered" # статус приложения после начала подмены
created_at: 2026-02-06 23:25:11
updated_at: 2026-02-06 23:25:11
При окончании режима подмены пользователя в журнале (таблица moonshine_change_logs) появится следующая запись:
id: 8
moonshine_user_id: 1 # пользователь, который остановил режим подмены (админ)
changelogable_type: App\Models\User # модель авторизации пользователя
changelogable_id: 4 # пользователь, которого подменяли
states_before: "impersonation_entered" # статус приложения до остановки подмены
states_after: "impersonation_stopped" # статус приложения после остановки подмены
created_at: 2026-02-06 23:25:37
updated_at: 2026-02-06 23:25:37
События
После старта и отмены режима подмены пользователя отправляются события ImpersonationEntered и ImpersonationStopped
соответственно. Оба эти события обладают следующими открытыми свойствами:
Authenticatable $impersonator- пользователь, запустивший/остановивший режим подмены (админ);Authenticatable $impersonated- пользователь, которого подменяют.
Расширенное использование
Расширенное использование подразумевает, что вы хорошо владеете админ-панелью MoonShine и фреймворком Laravel.
Пакет MoonShine Impersonate предоставляет кнопки действий EnterImpersonationActionButton и
StopImpersonationActionButton. Но вы можете самостоятельно реализовать свои кнопки, используя админ-панель
MoonShine и ресурсы данного пакета. Например, кнопки можно отрисовать в in-line или dropdown режимах.
Пример реализации кнопки включения режима подмены пользователя:
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Jampire\MoonshineImpersonate\Services\ImpersonateManager;
use MoonShine\UI\Components\ActionButton;
ActionButton::make(
label: 'Подменить пользователя',
url: static fn (Model $item): string => route('impersonate.enter', [
'resourceItem' => $item->getKey(),
]),
)
->canSee(
callback: fn (Authenticatable $item): bool => app(ImpersonateManager::class)->canEnter($item),
)
->icon('users');
Cписок ресурсов пакета MoonShine Impersonate
Jampire\MoonshineImpersonate\UI\ActionButtons\EnterImpersonationActionButton- кнопка включения режима подмены пользователяJampire\MoonshineImpersonate\UI\ActionButtons\StopImpersonationActionButton- кнопка отключения режима подмены пользователяJampire\MoonshineImpersonate\Services\ImpersonateManager- управления режимами подменыroute('impersonate.enter')-GETмаршрут включения режима подмены пользователяroute('impersonate.enter-confirm')-POSTмаршрут включения режима подмены пользователяroute('impersonate.stop')-GETмаршрут отключения режима подмены пользователяJampire\MoonshineImpersonate\Actions\EnterAction- включение режима подмены пользователяJampire\MoonshineImpersonate\Actions\StopAction- отключение режима подмены пользователяJampire\MoonshineImpersonate\Events\ImpersonationEntered- событие включения режима подмены пользователяJampire\MoonshineImpersonate\Events\ImpersonationStopped- событие отключения режима подмены пользователя
Ссылки
Дополнительные ресурсы
Функционал подмены пользователя реализуют некоторые админ-панели. Например: