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
- пользователь, которого подменяют.
Ссылки
Дополнительные ресурсы
Функционал подмены пользователя реализуют некоторые админ-панели. Например: