将您的应用程序部署到生产环境后,您可能偶尔需要“模拟”应用程序的另一个用户,以调试客户报告的问题。幸运的是,Nova 包含内置功能来处理这种确切的情况。
要启用用户模拟,请将Laravel\Nova\Auth\Impersonatable
特性添加到您的应用程序的User
模型中
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Nova\Auth\Impersonatable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Impersonatable, Notifiable;
// ...
}
将Impersonatable
特性添加到您的应用程序的User
模型后,将在相应资源的内联操作菜单中提供“模拟”操作
默认情况下,任何有权查看 Nova 仪表板的用户都可以模拟任何其他用户。但是,您可以通过在应用程序的Impersonatable
模型上定义canImpersonate
和canBeImpersonated
方法来自定义谁可以模拟其他用户以及哪些用户可以被模拟
use Illuminate\Support\Facades\Gate;
/**
* Determine if the user can impersonate another user.
*
* @return bool
*/
public function canImpersonate()
{
return Gate::forUser($this)->check('viewNova');
}
/**
* Determine if the user can be impersonated.
*
* @return bool
*/
public function canBeImpersonated()
{
return true;
}
通过 Laravel 的服务容器解析Laravel\Nova\Contracts\ImpersonatesUsers
接口的实现,您可以检查应用程序的当前模拟状态
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Laravel\Nova\Contracts\ImpersonatesUsers;
Route::get('/impersonation', function (Request $request, ImpersonatesUsers $impersonator) {
if ($impersonator->impersonating($request)) {
$impersonator->stopImpersonating($request, Auth::guard(), User::class);
}
});
默认情况下,您可以使用可用的模拟事件添加额外的自定义
Laravel\Nova\Events\StartedImpersonating
Laravel\Nova\Events\StoppedImpersonating
例如,您可能希望记录模拟事件,您可以在应用程序的AppServiceProvider
的boot
方法中注册监听器
use Illuminate\Support\Facades\Event;
use Laravel\Nova\Events\StartedImpersonating;
use Laravel\Nova\Events\StoppedImpersonating;
Event::listen(StartedImpersonating::class, function ($event) {
logger("User {$event->impersonator->name} started impersonating {$event->impersonated->name}");
});
Event::listen(StoppedImpersonating::class, function ($event) {
logger("User {$event->impersonator->name} stopped impersonating {$event->impersonated->name}");
});