Languages

Version

Theme

用户

概述

介绍

默认情况下,所有的 App\Models\User 用户可以在本地环境中访问 Filament。但如果要在生产环境中同样允许用户访问,需要一些额外的操作来确保授权的用户才能访问面板。

授权访问面板

要让非本地环境的 App\Models\User 用户获取访问权限,你需要实现 FilamentUser 合约接口:

<?php

namespace App\Models;

use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser
{
    // ...

    public function canAccessPanel(Panel $panel): bool
    {
        return str_ends_with($this->email, '@yourdomain.com') && $this->hasVerifiedEmail();
    }
}

canAccessPanel() 方法返回 true 还是 false,取决于用户是否被授权允许访问该面板 $panel。本例中会检查用户的邮箱后缀是否为 @yourdomain.com 以及用户是否验证过该邮箱。

既然你可以访问当前 $panel,你可以为不同的面板编写条件。比如,只对管理面板进行严格限权,而所有用户都可以访问其他的面板:

<?php

namespace App\Models;

use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser
{
    // ...

    public function canAccessPanel(Panel $panel): bool
    {
        if ($panel->getId() === 'admin') {
            return str_ends_with($this->email, '@yourdomain.com') && $this->hasVerifiedEmail();
        }

        return true;
    }
}

授权访问资源

请查阅资源文档的授权部分,了解如何控制资源页面以及其数据记录的的访问。

设置头像

Filament 使用可开箱即用的 ui-avatars.com 生成基于用户名的头像。不过,如果你的模型中有 avatar_url 属性,则会使用该属性。要自定义 Filament 获取用户头像 URL,你也可以实现 HasAvatar 合约接口:

<?php

namespace App\Models;

use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasAvatar;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser, HasAvatar
{
    // ...

    public function getFilamentAvatarUrl(): ?string
    {
        return $this->avatar_url;
    }
}

getFilamentAvatarUrl() 方法用于获取当前用户的头像。如果这个方法返回 null,Filament 会转向 ui-avatars.com

使用其他头像提供者

你可以创建一个新的头像提供者将 ui-avatars.com 替换成不同的服务.

本例中,我们为 boringavatars.com 创建了一个新文件 app/Filament/AvatarProviders/BoringAvatarsProvider.phpget() 方法接收一个用户模型实例并返回该用户的头像 URL:

<?php

namespace App\Filament\AvatarProviders;

use Filament\AvatarProviders\Contracts;
use Filament\Facades\Filament;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;

class BoringAvatarsProvider implements Contracts\AvatarProvider
{
    public function get(Model | Authenticatable $record): string
    {
        $name = str(Filament::getNameForDefaultAvatar($record))
            ->trim()
            ->explode(' ')
            ->map(fn (string $segment): string => filled($segment) ? mb_substr($segment, 0, 1) : '')
            ->join(' ');

        return 'https://source.boringavatars.com/beam/120/' . urlencode($name);
    }
}

现在,在配置文件中注册该 Provider:

use App\Filament\AvatarProviders\BoringAvatarsProvider;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->defaultAvatarProvider(BoringAvatarsProvider::class);
}

配置用户 name 属性

默认情况下,Filament 会使用用户的 name 属性来展示面板中的名字。想要调整,你可以实现 HasName 合约接口:

<?php

namespace App\Models;

use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasName;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser, HasName
{
    // ...

    public function getFilamentName(): string
    {
        return "{$this->first_name} {$this->last_name}";
    }
}

getFilamentName() 方法用于检索当前用户的名字。

身份认证功能

你可以在配置文件中为面板启用身份验证功能:

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->login()
        ->registration()
        ->passwordReset()
        ->emailVerification()
        ->emailChangeVerification()
        ->profile();
}

Filament 也支持多因素认证,你可以在多因素认证章节中了解更多详情。

自定义身份验证功能

如果你想使用你自己的页面替换掉这些页面,你可以在这些方法的中传入任何 Filament 页面类。

大部分人可以通过继承 Filament 代码库的基础页面类,重写 form() 这样的方法,并传入新页面类到配置中,来自定义他们的需求:

use App\Filament\Pages\Auth\EditProfile;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->profile(EditProfile::class);
}

本例中,我们将自定义 Profile 页面。我们需要创建一个新的 PHP 类 —— app/Filament/Pages/Auth/EditProfile.php

<?php

namespace App\Filament\Pages\Auth;

use Filament\Auth\Pages\EditProfile as BaseEditProfile;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;

class EditProfile extends BaseEditProfile
{
    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('username')
                    ->required()
                    ->maxLength(255),
                $this->getNameFormComponent(),
                $this->getEmailFormComponent(),
                $this->getPasswordFormComponent(),
                $this->getPasswordConfirmationFormComponent(),
            ]);
    }
}

该类继承了 Filament 代码库的基础 Profile 页面类。其他你需要继承的页面包括:

  • Filament\Pages\Auth\Login
  • Filament\Pages\Auth\Register
  • Filament\Pages\Auth\EmailVerification\EmailVerificationPrompt
  • Filament\Pages\Auth\PasswordReset\RequestPasswordReset
  • Filament\Pages\Auth\PasswordReset\ResetPassword

上例的 form() 方法中,我们调用了 getNameFormComponent() 以获取页面的默认表单组件。你可以按需求自定义这些组件。对于所有可用的自定义选项,请查看 Filament 代码库中的基础 EditProfile 页面类 —— 它包含你可以重写修改的所有方法。

自定义身份认证字段,而无需重新定义表单

如果你想自定义身份认证表单中的字段,而不必定义新的 form() 方法,你可以扩展自定义的字段方法并链式调用你的自定义内容:

use Filament\Schemas\Components\Component;

protected function getPasswordFormComponent(): Component
{
    return parent::getPasswordFormComponent()
        ->revealable(false);
}

邮箱修改验证

如果你同时 profile()emailChangeVerification() 特性,用户从 Profile 表单中修改邮箱地址会要求登录前验证他们的新邮箱地址。这是通过发送验证邮件到新邮箱地址中实现的,其中包含一个供用户点击以进行邮箱验证的链接。数据库中的邮箱地址在用户点击邮箱中的链接之前不会修改。

发送给用户的链接有效期为 60 分钟。发送到新邮箱地址的同时,也会发送另一封邮件到旧的邮箱地址,其中有一个链接用来防止修改。这是一种安全保护措施,可以潜在地防止用户受到恶意行为者的影响。

在 Profile 页面使用侧边栏

Profile 页面默认不会使用带有侧边栏的标准页面布局。这是为了使其与租户特性合作,否则,如果用户没有租户,它将无法访问,因为侧边栏链接被路由到当前租户。

如果你没有在面板中使用租户,并且想让 Profile 页面使用带侧边栏的标准页面布局,你可以在注册页面时,将 isSimple: false 参数传递给 $panel->profile()

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->profile(isSimple: false);
}

自定义认证路由 slug

你可以在配置中自定义用于身份认证路由的 URL slug:

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->loginRouteSlug('login')
        ->registrationRouteSlug('register')
        ->passwordResetRoutePrefix('password-reset')
        ->passwordResetRequestRouteSlug('request')
        ->passwordResetRouteSlug('reset')
        ->emailVerificationRoutePrefix('email-verification')
        ->emailVerificationPromptRouteSlug('prompt')
        ->emailVerificationRouteSlug('verify')
        ->emailChangeVerificationRoutePrefix('email-change-verification')
        ->emailChangeVerificationRouteSlug('verify');
}

身份验证保护

要设置 Filament 使用的 Authentication Guard,你可以将 guard 名传入到 authGuard() 配置方法中:

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->authGuard('web');
}

设置密码 Broker

要设置 Filament 使用的 Password Broker,你可以将 broker 名传入到 authPasswordBroker() 配置方法中:

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->authPasswordBroker('users');
}

禁用可显示的密码输入

默认情况下,所有认证表单的密码输入是 revealable()。这允许用户通过点击按钮查看其密码的明文版本。要禁用该特性,你可以传递 falserevealablePasswords() 配置方法中:

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->revealablePasswords(false);
}

你也可以在扩展基本页面类时,通过在字段对象上调用 ->reveable(false),基于字段禁用此功能:

设置访客访问面板

默认情况下,Filament 只希望认证用户使用。要允许访客访问面板,你需要避免使用需要用户登录的组件(如配置文件、头像),并删除内置的身份验证中间件:

  • 从面板配置文件的 authMiddleware() 数组中移除默认的 Authenticate::class
  • 移除 ->login() 以及面板中任何其他身份认证特性
  • widgets() 数组中移除默认的 AccountWidget,因为它会读取当前用户数据。

在策略中授权访客

如果存在,Filament 依赖于 Laravel 模型策略用于访问控制。为模型策略中的访客用户授予读取权限,创建策略并更新 viewAny()view() 方法,将 User $user参数更改为 ?User $user,以使其可选,并 return true;。或者,可以从策略中完全删除这些方法。

Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion