 
        
        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
MoonShine Impersonate предоставляет возможность подмены пользователя в проектах на Laravel с использованием админ-панели MoonShine. Функциональность подмены пользователя позволяет админстратору войти на сайт как реальный пользователь. Это может быть полезно, чтобы посмотреть, как сайт виден обычному пользователю, воспроизвести баги от его имени и т.д.
Содержимое
Установка
MoonShine Impersonate спроектирован для использования в составе админ-панели MoonShine. Поэтому, сперва установите 
админ-панель, следуя инструкциям с официального сайте MoonShine. Затем установите данный пакет при помощи 
команды:
composer require jampire/moonshine-impersonate
Настройка
MoonShine Impersonate способен работать из коробки с настройками по умолчанию. Но вы можете опубликовать его 
настройки в свою директорию config и изменть нужные пареметры (зачастую в файле .env):
php artisan vendor:publish --provider="Jampire\MoonshineImpersonate\ImpersonateServiceProvider" --tag=config
Также можно опубликовать все ресурсы пакета для ещё более тонкой настройки (или же по отдельным тегам lang, views, 
view-components):
php artisan vendor:publish --provider="Jampire\MoonshineImpersonate\ImpersonateServiceProvider"
Использование
Базовое использование
Т.к. данный пакет работает с системой авторизации, то применять его можно на модели User. Для этого создайте
MoonShine ресурс, использующий модель авторизации User вашего приложения.
Для примера, создадим следующий MoonShine ресурс:
<?php
declare(strict_types=1);
namespace App\MoonShine\Resources;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use MoonShine\Fields\Email;
use MoonShine\Fields\Text;
use MoonShine\Resources\Resource;
use MoonShine\Fields\ID;
use MoonShine\Actions\FiltersAction;
class UserResource extends Resource
{
    public static string $model = User::class;
    public static string $title = 'Users';
    public static string $orderType = 'ASC';
    public function fields(): array
    {
        return [
            ID::make()->sortable(),
            Text::make('Name', 'name'),
            Email::make('E-mail', 'email'),
        ];
    }
    public function rules(Model $item): array
    {
        return [];
    }
    public function search(): array
    {
        return ['id'];
    }
    public function filters(): array
    {
        return [];
    }
    public function actions(): array
    {
        return [
            FiltersAction::make(trans('moonshine::ui.filters')),
        ];
    }
    public function itemActions(): array
    {
        return [];
    }
}
Для добавления действия подмены пользователя пакет MoonShine Impersonate предоставляет своё действие карточки 
EnterImpersonationItemAction. Для его добавления воспользуйтесь методом itemActions() ресурса UserResource:
<?php
declare(strict_types=1);
namespace App\MoonShine\Resources;
use Jampire\MoonshineImpersonate\UI\ItemActions\EnterImpersonationItemAction;
use MoonShine\Resources\Resource;
class UserResource extends Resource
{
    // ...
    public function itemActions(): array
    {
        return [
            EnterImpersonationItemAction::make()->resolve(),
        ];
    }
}
За тонкую настройку этого действия отвечают секция buttons.enter файла конфигурации и секция ui.buttons.enter 
файлов локализации.
После подключения данного действия ваш ресурс Users может выглядеть следующим образом:

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

В заголовке админ-панели появится кнопка 
Остановить подмену пользователя, которая будет видна на любой странице админ-панели. Таким образом, вы всегда 
будите помнить, что находитесь в режиме подмены пользователя:

За отрисовку данной кнопки отвечает опция buttons.stop.enabled файла конфигурации. Эта опция перезапишет содержимое 
опции header файла конфигурации moonshine. Если это не то, что вам нужно, вы можете отключить отрисовку кнопки 
в файле .env при помощи переменной окружения MS_IMPERSONATE_STOP_BUTTON_ENABLED:
MS_IMPERSONATE_STOP_BUTTON_ENABLED=false
а саму кнопку установить в нужном вам месте при помощи компонента x-impersonate-stop.
Middleware
Для своей работы режим подмены пользователя использует ImpersonateMiddleware класс. По-умолчанию он работает с 
маршрутами (routes) в группе web. Если вы хотите добавить этот middleware к другим маршрутам, воспольуйтесь 
псевдонимом impersonate. Например, его можно подключить в контроллере:
class PostController extends Controller
{
    public function __construct()
    {
        $this->middleware('impersonate');
    }
}
Разрешения
По умолчанию, любой администратор может подменять любого пользователя. Если вы желаете более тонкую настройку 
разрешений (permissions), можно воспользоваться интерфейсами Impersonable и BeImpersonable и реализовать методы 
canImpersonate() и canBeImpersonated() соответственно.
Например, чтобы контролировать, кто из админстраторов может подменять пользователя, нужно реализовать метод 
canImpersonate() на моделе администратора MoonshineUser:
<?php
declare(strict_types=1);
namespace App\Models;
use Jampire\MoonshineImpersonate\Services\Contracts\Impersonable;
use MoonShine\Models\MoonshineUser as BaseUser;
use MoonShine\Models\MoonshineUserRole;
class MoonshineUser extends BaseUser implements Impersonable
{
    // ...
    public function canImpersonate(): bool
    {
        return $this->moonshine_user_role_id === MoonshineUserRole::DEFAULT_ROLE_ID;
    }
}
А чтобы контролировать, кого из пользователей можно подменять, нужно реализовать метод canBeImpersonated() 
на моделе авторизации User:
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Foundation\Auth\User as BaseUser;
use Illuminate\Support\Str;
use Jampire\MoonshineImpersonate\Services\Contracts\BeImpersonable;
class User extends BaseUser implements BeImpersonable
{
    // ...
    public function canBeImpersonated(): bool
    {
        return !Str::endsWith($this->email, '@verysecureemail.com');
    }
}
Запись событий (логирование)
Если вы желаете, то можете включить запись событий переключения пользователя в журнал MoonShine (по-умолчанию 
отключено). Включение режима записи осуществляется путём добавления трейта HasMoonShineChangeLog к модели авторизации 
User (согласно документации MoonShine):
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use MoonShine\Traits\Models\HasMoonShineChangeLog;
class User extends Authenticatable
{
    use HasMoonShineChangeLog;
    // ...
}
При старте режима подмены пользователя в журнале (таблица 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: 2023-05-25 23:25:11
updated_at: 2023-05-25 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: 2023-05-25 23:25:37
updated_at: 2023-05-25 23:25:37
События
После старта и отмены режима подмены пользователя отправляются события ImpersonationEntered и ImpersonationStopped 
соответственно. Оба эти события обладают следующими открытыми свойствами:
- Authenticatable $impersonator- пользователь, запустивший/остановивший режим подмены (админ);
- Authenticatable $impersonated- пользователь, которого подменяют.
Ссылки
Дополнительные ресурсы
Функционал подмены пользователя реализуют некоторые админ-панели. Например: