ferdiunal / nova-shield
一个用于管理权限和角色的 Laravel Nova 扩展包。
Requires
- php: ^8.2
- laravel/framework: ^11.0
- laravel/nova: ^4.0
- spatie/laravel-permission: ^6.9
README
Nova Shield 通过使用 Spatie Permission 简化了您 Laravel Nova 资源的权限管理。您可以轻松地授予或撤销对特定资源和操作的访问权限,从而简化工作流程并提高安全性。
安装
composer require ferdiunal/nova-shield
配置
可选地,您可以使用以下命令发布配置文件
php artisan vendor:publish --tag nova-shield-config
在配置文件中,您可以通过指定资源参数来控制资源权限,参数可以是 Nova 资源文件夹的路径或字符串类路径。
例如,在下面的代码中,我们定义了资源和相应的策略
显示代码
<?php return [ /** * Specify the resources that will be used in the project. * If you want to use custom resources, you can add them to the list. */ 'resources' => [ app_path('Nova'), \Ferdiunal\NovaShield\Http\Nova\ShieldResource::class, // Custom resource: For custom menu items // [ // "name" => "Custom Menu Item", // "prefix" => "customMenuItem::", // "policies" => ["CustomMenuPolicy"] // Add custom menu policies here // ] ], // 'teamFields' => \App\Lib\TeamField::class, /** * Constant policies of Laravel Nova */ 'policies' => [ 'viewAny', 'view', 'create', 'update', 'replicate', 'delete', 'restore', 'forceDelete', 'runAction', 'runDestructiveAction', 'canImpersonate', 'canBeImpersonated', 'add{Model}', 'attach{Model}', 'attachAny{Model}', 'detach{Model}', ], /** * Specify the file path of each language files for authorisations. */ 'langs' => [ // lang_path('en/nova-shield.json'), // base_path('langs/en/nova-shield.json'), ], /** * Default Super admin role name and guard */ 'superAdmin' => [ 'name' => 'super-admin', 'guard' => 'web', ], 'hooks' => [ /** * When matching permissions with roles, upsert is used by default. * If you are using custom ID types like UUID or ULID, you need to include them in the upsert operation. * Therefore, you can write and use a query that suits your project needs. */ 'permission' => \Ferdiunal\NovaShield\Lib\DefaultPermissionHook::class, ], ];
自定义菜单配置
该包的主要目的是管理 Nova 资源的权限,但我意识到还需要自定义菜单的支持。必要的开发工作已经完成。您可以参考以下用法来实现自定义菜单。
// app/Providers/NovaServiceProvider.php Nova::mainMenu(function (Request $request) { return [ MenuItem::make('Custom Menu Item') ->path('/custom-menu') ->canSee( function ($request) { return $request->user()->can('CustomMenuPolicy'); } ) ]; }); // ---- // config/nova-shield.php return [ "resources" => [ ... // Custom resource: For custom menu items [ "name" => "Custom Menu Item", "prefix" => "customMenuItem::", "policies" => ['CustomMenuPolicy'] // Add custom menu policies here ] ] ];
然后按照以下方式编辑 App\Nova\Resource.php 文件。
<?php namespace App\Nova; use Ferdiunal\NovaShield\PermissionAuthorizable; use Laravel\Nova\Resource as NovaResource; abstract class Resource extends NovaResource { use PermissionAuthorizable; .... }
团队支持
我假设您已经为 Spatie Permission 完成了团队集成,并且您可以按照以下设置进行 NovaShield 的配置。
模型集成
团队功能在每个项目中都不同,请根据您的项目填写相关方法。
// App\Models\User use Ferdiunal\NovaShield\Contracts\HasShieldTeam; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements HasShieldTeam { public function getTeamIdAttribute(): mixed { // return $this->team_id } }
添加团队字段
考虑到团队功能在每个项目中都可能不同,您需要自己添加团队字段。
namespace App\Lib; use Ferdiunal\NovaShield\Lib\NovaTeamHelperField; use Laravel\Nova\Fields\Field; use Laravel\Nova\Fields\Select; class TeamField extends NovaTeamHelperField { public static function field(): Field { return Select::make('Teams', 'team_id') ->options([]) ->displayUsingLabels() ->searchable() ->sortable(); } }
添加 Nova 路由中间件
添加 TeamMiddleware 到 nova 路由
return [ /* |-------------------------------------------------------------------------- | Nova Route Middleware |-------------------------------------------------------------------------- | | These middleware will be assigned to every Nova route, giving you the | chance to add your own middleware to this stack or override any of | the existing middleware. Or, you can just stick with this stack. | */ 'middleware' => [ .... \Ferdiunal\NovaShield\Http\Middleware\TeamMiddleware::class, ], ];
命令
该包包含两个不同的命令。第一个命令检查超级管理员角色是否存在,如果不存在则创建它,并将配置文件中指定的资源权限分配给它。第二个命令用于将超级管理员角色分配给用户。
同步超级管理员角色和权限命令
php artisan artisan nova-shield:sync-super-admin
将超级管理员角色分配给用户命令
php artisan nova-shield:super-admin
权限同步钩子
在将权限映射到角色时,默认使用 upsert。如果您使用自定义 ID 类型(如 UUID 或 ULID),则 upsert 无法识别这些 ID。因此,您可以编写并使用适合项目需求的自定义查询。
示例钩子:
// app/SyncPermissionHook.php <?php namespace App; use Ferdiunal\NovaShield\Contracts\SyncPermissionHook as SyncPermissionHookContract; use Illuminate\Support\LazyCollection; use Illuminate\Support\Str; use Spatie\Permission\Contracts\Role; use Spatie\Permission\Models\Permission; class SyncPermissionHook implements SyncPermissionHookContract { /** * Sync permissions to a role * * @param array<int,string> $permissions * @return void */ public function __invoke(Role $role, $permissions) { Permission::query()->upsert( LazyCollection::make($permissions) ->map(function ($permission) use (&$role) { return [ 'id' => Str::uuid(), 'name' => $permission, 'guard_name' => $role->guard_name, 'created_at' => now(), 'updated_at' => now(), ]; })->toArray(), ['name', 'guard_name'], ['name', 'guard_name'], ); $role->syncPermissions($permissions); } }
您需要将配置文件中创建的类替换为默认类。
示例:
// config/nova-shield.php return [ 'hooks' => [ /** * When matching permissions with roles, upsert is used by default. * If you are using custom ID types like UUID or ULID, you need to include them in the upsert operation. * Therefore, you can write and use a query that suits your project needs. */ 'permission' => \App\SyncPermissionHook::class, ], ];
屏幕截图
许可协议 本软件包是开源软件,根据 MIT 许可协议 许可。





