bezhansalleh / filament-shield
Filament对`spatie/laravel-permission`的文件支持。
Requires
- php: ^8.1
- filament/filament: ^3.2
- spatie/laravel-package-tools: ^1.9
- spatie/laravel-permission: ^6.0
Requires (Dev)
- larastan/larastan: ^2.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.0|^8.0
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- phpunit/phpunit: ^10.1
- 3.x-dev
- 3.2.6
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.13
- 3.0.12
- 3.0.11
- 3.0.10
- 3.0.9
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 3.0.0-beta2
- 3.0.0-beta1
- 2.x-dev
- v2.5.0
- 2.4.9
- 2.4.8
- 2.4.7
- 2.4.6
- 2.4.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.3
- 2.1.2
- 2.1.1
- v2.1.0
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- 1.x-dev
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feature/handle-role-policy-auto-registration
- dev-feature/spatie-permission-6-support
This package is auto-updated.
Last update: 2024-09-02 19:00:10 UTC
README

护盾
为您的Filament Admin添加访问管理的最简单、最直观的方式
- 🔥 资源
- 🔥 页面
- 🔥 小部件
- 🔥 自定义权限
注意
对于 Filament 2.x 使用 2.x 分支
重要
在 v3.1.0
之前,护盾支持 spatie/laravel-permission:^5.0
,现在它支持版本 ^6.0
。这涉及一些关于迁移的重大更改。如果您是从 v3.1.0
之前的版本升级的,请确保删除旧的迁移文件并重新发布新的迁移文件。
安装
- 通过composer安装包
composer require bezhansalleh/filament-shield
- 将
Spatie\Permission\Traits\HasRoles
特性添加到您的User模型
use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; // ... }
- 发布
config
文件,然后设置您的配置
php artisan vendor:publish --tag=filament-shield-config
- 为要使用的Filament面板注册插件
public function panel(Panel $panel): Panel { return $panel ->plugins([ \BezhanSalleh\FilamentShield\FilamentShieldPlugin::make() ]); }
- 现在运行以下命令以安装护盾
php artisan shield:install
按照提示操作,享受!
Filament面板
如果您想要为多个面板启用Shield
,则需要按上述方式为每个面板注册插件。
面板访问
Shield提供了HasPanelShield
特性,该特性提供了一个轻松的方式将Shield的约定与Filament的面板访问系统集成。
HasPanelShield
特性为canAccessPanel
方法提供了一个实现,根据用户是否拥有super_admin
角色或panel_user
角色来确定访问权限。它还在创建用户时分配panel_user
角色,并在删除用户时移除它。当然,角色名称可以由插件的配置文件更改。
use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Filament\Models\Contracts\FilamentUser; use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable implements FilamentUser { use HasRoles; use HasPanelShield; // ... }
资源
通常,Shield处理以下两种情况下的Filament
资源权限。
默认
默认情况下,Shield处理Filament
资源的预定义权限。因此,如果您需要的就是这些,那么您已经准备好了。如果您需要添加单个权限(例如lock
),并使其对所有资源可用,只需将其追加到以下config
键即可
permission_prefixes' => [ 'resource' => [ 'view', 'view_any', 'create', 'update', 'restore', 'restore_any', 'replicate', 'reorder', 'delete', 'delete_any', 'force_delete', 'force_delete_any', 'lock' ], ... ],
💡 现在您可能在想 如果我只想要一个资源可用权限怎么办?
没关系,这正是自定义权限发挥作用的地方。
自定义权限
为了为每个Resource
定义自定义权限,您的Resource
必须实现HasShieldPermissions
协议。此协议有一个getPermissionPrefixes()
方法,它返回一个包含您Resource
的权限前缀的数组。
假设您有一个PostResource
,您想为预定义的权限加上一个名为publish_posts
的新权限,并且只对PostResource
可用。
<?php namespace BezhanSalleh\FilamentShield\Resources; use BezhanSalleh\FilamentShield\Contracts\HasShieldPermissions; ... class PostResource extends Resource implements HasShieldPermissions { ... public static function getPermissionPrefixes(): array { return [ 'view', 'view_any', 'create', 'update', 'delete', 'delete_any', 'publish' ]; } ... }
在上面的示例中,getPermissionPrefixes()
方法返回Shield生成权限所需的权限前缀。
✅ 现在将 publish_post
权限头传递到您的 PostPolicy
并添加一个 publish()
方法
/** * Determine whether the user can publish posts. * * @param \App\Models\User $admin * @return \Illuminate\Auth\Access\Response|bool */ public function publish(User $user) { return $user->can('publish_post'); }
🅰️/🈯️ 要使前缀可翻译,发布 Shield
的翻译,并在 resource_permission_prefixes_labels
中将前缀作为键,将其翻译作为值添加到您需要的语言中。
//lang/en/filament-shield.php 'resource_permission_prefixes_labels' => [ 'publish' => 'Publish' ], //lang/es/filament-shield.php 'resource_permission_prefixes_labels' => [ 'publish' => 'Publicar' ],
配置权限标识符
默认情况下,权限标识符生成如下
Str::of($resource) ->afterLast('Resources\\') ->before('Resource') ->replace('\\', '') ->snake() ->replace('_', '::');
例如,如果您有一个资源如 App\Filament\Resources\Shop\CategoryResource
,则权限标识符将为 shop::category
,然后它将带有您定义的前缀或Shield默认提供的前缀。
如果您希望更改默认行为,则可以在服务提供者的 boot()
方法中调用静态 configurePermissionIdentifierUsing()
方法,并传递一个闭包来修改逻辑。闭包接收资源的完全限定类名作为 $resource
,这使得您可以访问资源中定义的任何属性或方法。
例如,如果您希望使用模型名称作为权限标识符,可以这样做
use BezhanSalleh\FilamentShield\Facades\FilamentShield; FilamentShield::configurePermissionIdentifierUsing( fn($resource) => str($resource::getModel()) ->afterLast('\\') ->lower() ->toString() );
警告 请注意,确保权限标识符的唯一性现在由您负责。
自定义导航组
默认情况下,英语翻译将“角色和权限”显示为“Filament Shield”下的内容。如果您想更改这一点,首先发布翻译文件并更改相对区域设置为您的选择组,例如
'nav.group' => 'Filament Shield',
到
'nav.group' => 'User Management',
将此应用到您拥有的每个语言组。
页面
如果您为 Pages
生成权限,您可以切换侧边栏中的页面导航并限制对页面的访问。您可以手动设置此操作,但此包附带一个 HasPageShield
特性以加快此过程。您只需在页面中使用此特性即可。
<?php namespace App\Filament\Pages; use ...; use BezhanSalleh\FilamentShield\Traits\HasPageShield; class MyPage extends Page { use HasPageShield; ... }
📕 HasPageShield
使用 booted
方法检查用户的权限,并确保在父页面中执行 booted
页面方法(如果存在)。
页面钩子
但是,如果您需要在 booted
方法之前和之后执行某些方法,您可以在 Filament 页面中声明以下钩子方法。
<?php namespace App\Filament\Pages; use ...; use BezhanSalleh\FilamentShield\Traits\HasPageShield; class MyPage extends Page { use HasPageShield; ... protected function beforeBooted : void() { ... } protected function afterBooted : void() { ... } /** * Hook to perform an action before redirect if the user * doesn't have access to the page. * */ protected function beforeShieldRedirects : void() { ... } }
页面重定向路径
HasPageShield
默认使用 config('filament.path')
值执行 Shield 重定向。如果您需要覆盖重定向路径,只需将以下方法添加到页面中即可。
<?php namespace App\Filament\Pages; use ...; use BezhanSalleh\FilamentShield\Traits\HasPageShield; class MyPage extends Page { use HasPageShield; ... protected function getShieldRedirectPath(): string { return '/'; // redirect to the root index... } }
小部件
如果您为 Widgets
生成权限,您可以根据用户是否有权限来切换它们的状态。您可以手动设置此操作,但此包附带一个 HasWidgetShield
特性以加快此过程。您只需在您的小部件中使用此特性即可。
<?php namespace App\Filament\Widgets; use ...; use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; class IncomeWidget extends LineChartWidget { use HasWidgetShield; ... }
策略
角色策略
使用 Laravel 10
为确保通过 RolePolicy
访问 RoleResource
,您需要在您的 AuthServiceProvider
中添加以下内容
//AuthServiceProvider.php ... protected $policies = [ 'Spatie\Permission\Models\Role' => 'App\Policies\RolePolicy', ]; ...
使用 Laravel 11
为确保通过 RolePolicy
访问 RoleResource
,您需要在您的 AppServiceProvider
中添加以下内容
//AppServiceProvider.php use Illuminate\Support\Facades\Gate; ... public function boot(): void { ... Gate::policy(\Spatie\Permission\Models\Role::class, \App\Policies\RolePolicy::class); } ...
无论您的 Laravel 版本如何,如果您已在 config
中启用,则可以跳过此步骤。
// config/filament-shield.php ... 'register_role_policy' => [ 'enabled' => true, ], ...
策略路径
如果您的策略不在默认的 Policies
目录中(位于 app_path()
),您可以在配置文件中更改目录名称。
... 'generator' => [ 'option' => 'policies_and_permissions', 'policy_directory' => 'Policies', ], ...
为模型或第三方插件自定义文件夹结构
Shield 还为具有自定义文件夹结构的第三方插件和 Models
生成策略和权限,要执行生成的策略,您需要将它们注册。
使用 Laravel 10
//AuthServiceProvider.php ... class AuthServiceProvider extends ServiceProvider { ... protected $policies = [ ..., 'App\Models\Blog\Author' => 'App\Policies\Blog\AuthorPolicy', 'Ramnzys\FilamentEmailLog\Models\Email' => 'App\Policies\EmailPolicy' ];
使用 Laravel 11
//AppServiceProvider.php use Illuminate\Support\Facades\Gate; ... class AppServiceProvider extends ServiceProvider { ... public function boot(): void { ... Gate::policy(\App\Models\Blog\Author::class, \App\Policies\Blog\AuthorPolicy::class); Gate::policy(\Ramnzys\FilamentEmailLog\Models\Email::class, \App\Policies\EmailPolicy::class); }
用户(将角色分配给用户)
盾牌组件默认不提供分配用户角色的功能,但是您可以使用 Filament Forms
的 Select
或 CheckboxList
组件轻松地为您的用户分配角色。在您的用户 Resource
的表单中添加其中一个组件,并根据需要配置它们
// Using Select Component Forms\Components\Select::make('roles') ->relationship('roles', 'name') ->multiple() ->preload() ->searchable() // Using CheckboxList Component Forms\Components\CheckboxList::make('roles') ->relationship('roles', 'name') ->searchable()
有关这些组件的更多信息,请参阅 Filament 文档
布局定制
您可以在不发布资源的情况下轻松自定义 Grid
、Section
和 CheckboxList
的 columns()
和 columnSpan()
use BezhanSalleh\FilamentShield\FilamentShieldPlugin; public function panel(Panel $panel): Panel { return $panel ... ... ->plugins([ FilamentShieldPlugin::make() ->gridColumns([ 'default' => 1, 'sm' => 2, 'lg' => 3 ]) ->sectionColumnSpan(1) ->checkboxListColumns([ 'default' => 1, 'sm' => 2, 'lg' => 4, ]) ->resourceCheckboxListColumns([ 'default' => 1, 'sm' => 2, ]), ]); }

翻译
使用以下方式发布翻译
php artisan vendor:publish --tag="filament-shield-translations"
可用的 Filament Shield 命令
shield:doctor
- 显示 Filament Shield 的有用信息。
shield:install
设置核心包要求并安装 Shield。接受以下标志
--fresh
重新运行迁移--only
只设置 shield 而不生成权限和创建超级管理员
shield:generate
为 Filament 实体生成权限和/或策略。接受以下标志
--all
为所有实体生成权限/策略--option[=OPTION]
覆盖配置生成器选项(policies_and_permissions
、policies
、permissions
)--resource[=RESOURCE]
一个或多个资源,以逗号 (,) 分隔--page[=PAGE]
一个或多个页面,以逗号 (,) 分隔--widget[=WIDGET]
一个或多个小部件,以逗号 (,) 分隔--exclude
在生成时排除指定的实体--ignore-config-exclude
在生成时忽略配置exclude
选项--ignore-existing-policies
不要覆盖现有策略。
shield:super-admin
创建一个具有超级管理员角色的用户。
- 接受一个
--user=
参数,该参数将使用提供的 ID 来查找要成为超级管理员的用户。
shield:publish
- 发布 Shield
RoleResource
并按需自定义它
shield:seeder
- 通过设置您的角色和权限或添加自定义种子轻松部署
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 变更日志
贡献
有关详细信息,请参阅 贡献指南
安全漏洞
请审查我们如何报告安全漏洞的 安全策略
鸣谢
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件