outl1ne / nova-permissions
Laravel Nova 权限(基于角色和权限的访问控制)
Requires
- php: >=8.0
- benjaminhirsch/nova-slug-field: ^1.2.3
- laravel/nova: ^4.0
- silvanite/brandenburg: ^1.0
README
通过用户角色和权限,将访问控制添加到您的 Nova 安装中。包括默认的用户和角色策略,可以通过 Nova 管理面板进行管理。
该工具在内部使用 Silvanite\Brandenburg 包来管理用户角色。Brandenburg 被使用是因为它有明确的关注点分离。
此包是 Silvanite/novatoolpermissions 的未维护的 Nova 3 版本的分支。
屏幕截图
前提
角色 定义在 数据库 中
权限 定义在 代码库 中
因此,您将看不到任何 权限 资源。角色资源将从您代码中定义的门控器获取权限。
安装
使用 composer 安装此工具
composer require outl1ne/nova-permissions
运行迁移以添加 Brandenburg 所需的数据库表。
php artisan migrate
根据 Brandenburg 安装说明,将 HasRoles
特性添加到您的用户模型中。
// app/User.php use Silvanite\Brandenburg\Traits\HasRoles; class User extends Authenticatable { use HasRoles; ... }
将其加载到您的 Nova 工具中,以在资源中显示角色
// app/Providers/NovaServiceProvider.php use Outl1ne\NovaPermissions\NovaPermissions; public function tools() { return [ new NovaPermissions(), ]; }
您可以从角色资源中分配用户到角色,但是如果您想从用户资源中分配角色,您需要添加一个额外的关系。
// app/Nova/User.php use Outl1ne\NovaPermissions\Nova\Resources\Role; public function fields(Request $request) { return [ ... BelongsToMany::make('Roles', 'roles', Role::class), ]; }
如果您不使用默认的 App\Nova\User
资源,可以通过发布 nova-permissions
配置并设置您的用户资源模型来自定义此内容。
php artisan vendor:publish --provider="Outl1ne\NovaPermissions\Providers\PackageServiceProvider"
删除默认的 viewNova
门控器,以使用此包包含的门控器。您需要保留 gate() 方法,但将其清空。注意:Nova 总是在开发环境中允许访问。
// app/Providers/NovaServiceProvider.php protected function gate() { // }
用法
安装后,创建您的第一个角色。例如,创建 管理员
并将所有权限分配给新角色。
最后将管理员角色分配给您的用户帐户。
注意:默认情况下,如果没有单个用户有权访问权限,此包允许任何人访问权限。这是为了防止您将自己锁在外面。因此,定义具有所有权限的主管理员角色非常重要,这意味着除非您明确授予,否则没有人可以访问。
默认权限
此包附带一组默认权限,以提供对包功能的完全访问控制。权限附带默认英文翻译,以提供更好的用户体验。您可以在应用程序的 json 翻译中替换这些翻译。
{ "viewNova": "Access Nova", "viewRoles": "View Roles", "manageRoles": "Manage Roles", "assignRoles": "Assign Roles", "viewUsers": "View Users", "manageUsers": "Manage Users" }
自定义权限
要创建自己的权限,只需在服务提供者中定义它们,并为您的资源/模型创建一个 策略。让我们以一个常见的 博客 例子为例,并假设您在应用程序中有一个 博客 模型和资源。
为您的 Nova 资源创建一个 策略
为您的博客创建一个新的策略
php artisan make:policy BlogPolicy
让我们分配策略并定义我们的门控器。
// app/Providers/AuthServiceProvider.php use Silvanite\Brandenburg\Traits\ValidatesPermissions; class AuthServiceProvider extends ServiceProvider { use ValidatesPermissions; protected $policies = [ \App\Blog::class => \App\Policies\BlogPolicy::class, ]; public function boot() { collect([ 'viewBlog', 'manageBlog', ])->each(function ($permission) { Gate::define($permission, function ($user) use ($permission) { if ($this->nobodyHasAccess($permission)) { return true; } return $user->hasRoleWithPermission($permission); }); }); $this->registerPolicies(); } }
最后,根据 Nova 文档在策略中指定访问控制。
// app/Policies/BlogPolicy.php use Illuminate\Support\Facades\Gate; public function viewAny($user) { return Gate::any(['viewBlog', 'manageBlog'], $user); } public function view($user, $post) { return Gate::any(['viewBlog', 'manageBlog'], $user, $post); } public function create($user) { return $user->can('manageBlog'); } public function update($user, $post) { return $user->can('manageBlog', $post); } public function delete($user, $post) { return $user->can('manageBlog', $post); } public function restore($user, $post) { return $user->can('manageBlog', $post); } public function forceDelete($user, $post) { return $user->can('manageBlog', $post); }
并将您的标签添加到翻译中,以保持一切整洁。
{ "viewBlog": "View Blog", "manageBlog": "Manage Blog" }
这个示例是一个非常简单的实现。您可以在任何标准的Laravel应用程序中定义您的门,并简单地添加额外的检查来验证它们与分配的角色和权限。
访问控制
有时您可能想要阻止一些用户访问内容,但不阻止其他人。为了实现这一点,请在您的模型上使用包含的HasAccessControl.php
特性。
为了检查用户是否有查看您内容的正确权限,可以加载AccessControlServiceProvider
来全局注册accessControl
门。或者,在您的模型策略上包含AccessControlGate
特性。
在您的Nova资源中添加访问控制字段。这将显示所有具有canBeGivenAccess
权限的角色。为了保护内容不被访问,至少必须将一个角色授予对模型的访问权限,否则资源将对所有人开放。
public function fields(Request $request) { return [ // ... AccessControl::make(), // ... ] }
致谢
- Marco Mark (@m2de) - Silvanite/novatoolpermissions的原始创建者
- Tarvo Reinpalu
许可证
Nova Permissions是开源软件,许可协议为MIT许可证。