logo

模拟登录

概述

将您的应用程序部署到生产环境后,您可能偶尔需要“模拟”应用程序的另一个用户,以调试客户报告的问题。幸运的是,Nova 包含内置功能来处理这种确切的情况。

启用模拟登录

要启用用户模拟,请将Laravel\Nova\Auth\Impersonatable 特性添加到您的应用程序的User 模型中

php
<?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 模型后,将在相应资源的内联操作菜单中提供“模拟”操作

Impersonation

自定义模拟授权

默认情况下,任何有权查看 Nova 仪表板的用户都可以模拟任何其他用户。但是,您可以通过在应用程序的Impersonatable 模型上定义canImpersonatecanBeImpersonated 方法来自定义谁可以模拟其他用户以及哪些用户可以被模拟

php
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 接口的实现,您可以检查应用程序的当前模拟状态

php
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

例如,您可能希望记录模拟事件,您可以在应用程序的AppServiceProviderboot 方法中注册监听器

php
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}");
});