Spatie Laravel Permission
在 modules 中使用 Spatie permissions
Spatie为Laravel提供了强大的角色和权限包。这是管理完整角色的好方法,每个角色都有自己的权限。
有关完整的详细信息,请参阅他们的文档spatie.be/docs/laravel-permission/...
安装
使用composer安装这个包:
composer require spatie/laravel-permission
发布迁移和配置文件:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
这表示这些文件已经发布:
Copied File [/vendor/spatie/laravel-permission/config/permission.php] To [/config/permission.php]
Copied File [/vendor/spatie/laravel-permission/database/migrations/create_permission_tables.php.stub] To [/database/migrations/2021_12_22_111730_create_permission_tables.php]
Publishing complete.
在这一点上,文档建议迁移数据库,我们还没有准备好。我们需要更改迁移以包含模块,但首先我们希望将所有角色和权限相关文件移动到名为roles
的新模块中。
创建一个roles模块
php artisan module:make Roles
现在将 create_permission_tables.php
文件从 database/migrations
移动到新的 Roles 模块 Modules/Roles/database/migrations
打开create_permission_tables.php
文件,在权限模式中添加模块:
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name'); // MySQL 8.0 使用 string('name', 125);
$table->string('module'); // MySQL 8.0 使用 string('module', 125);
$table->string('guard_name'); // MySQL 8.0 使用 string('guard_name', 125);
$table->timestamps();
$table->unique(['name', 'guard_name']);
});
创建权限时,应使用模块键将权限分组到其模块。
例如:
这将来自于每个模块的 seeder 类,这个例子来自于一个管理模块
创建查看仪表板的权限,模块的管理模块和使用 web guard。
use Spatie\Permission\Models\Permission;
Permission::firstOrCreate(['name' => 'View Dashboard', 'module' => 'Admin', 'guard_name' => 'web']);
然后检查权限,用法与包文档相同,这里不检查模块设置。模块设置仅用于将权限分组到一个UI中,以便通过它们的模块管理权限。
auth()->user()->hasPermissionTo('View Dashboard')
填充用户角色
通常你想在应用中创建一个默认用户,并将他们设置为管理员,为此,你可以在填充类中创建一个用户。为此,我在 run
方法中使用Modules/Roles/Database/Seeders/RolesDatabaseSeeder.php
。
在尝试分配角色之前,角色应该已经存在:
use Spatie\Permission\Models\Role;
Role::firstOrCreate(['name' => 'Admin']);
Role::firstOrCreate(['name' => 'User']);
使用 firstOrCreate 意味着 seeder 可以运行多次,这样只会创建一个用户。
创建用户后,将为该用户分配 Admin 角色。
public function run()
{
app()['cache']->forget('spatie.permission.cache');
$admin = User::firstOrCreate([
'name' => 'Joe',
'slug' => 'Bloggs',
'email' => 'j.bloggs@domain.com'
],
[
'password' => bcrypt('a-random-password')
]);
$admin->assignRole('Admin');
}
为角色分配所有权限
如果你需要为一个角色分配所有权限,收集权限id的数组:
$permissions = Permission::all()->pluck('id')->toArray();
然后选择一个角色并同步权限数组:
$role = Role::find(1);
$role->syncPermissions($permissions);
按角色对权限进行分组
找一个特定的角色。
从 permissions 中获取所有模块,使用 distinct 删除重复的模块名称。
$role = Role::findOrFail($id);
$modules = Permission::select('module')->distinct()->orderBy('module')->get()->toArray();
然后在视图循环中遍历 modules 数组
@foreach($modules as $module)
在每个循环中提取他们的权限,以显示模块名称:
Str::camel($module['module'])
显示模块的所有权限:
@foreach (\Spatie\Permission\Models\Permission::where('module', $module['module'])->get() as $perm)
然后使用 $perm
来显示权限名称 {{$perm->name}}
不加任何样式就把它们放在一起:
@foreach($modules as $module)
<h3>{{ Str::camel($module['module']) }}</h3>
<table>
<thead>
<tr>
<th>Permisson</th>
<th>Action</th>
</tr>
</thead>
@foreach (\Spatie\Permission\Models\Permission::where('module', $module['module'])->get() as $perm)
<tr>
<td>{{ $perm->name }}</td>
<td><input type="checkbox" name="permission[]" value="{{ $perm->id }}" {{ $role->hasPermissionTo($perm->name) ? 'checked' : null }} /></td>
</tr>
@endforeach
</table>
@endforeach
使用 syncPermissions 更新角色权限
一旦你获得了权限数组,你就可以更新保存在角色中的权限。这将从透视表中删除所有不在 $permissions
数组中的角色权限。
$role->syncPermissions($permissions);