简介
Laravel-permission 是可以快速实现权限和角色需求的权限管理扩展包。
安装
通过 Composer 安装:1
composer "spatie/laravel-permission:~2.7"
在 Laravel 5.5 中 service provider 会自动注册,旧版本的Laravel中你需要像以下这样自行添加到 config/app.php 中:1
2
3
4'providers' => [
// ...
Spatie\Permission\PermissionServiceProvider::class,
];
生成数据库迁移文件:1
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
创建数据表1
php artisan migrate
生成配置信息:1
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
生成的配置文件放置 config/permission.php。
用法
1. 加载 HasRoles
1 | use Spatie\Permission\Traits\HasRoles; |
此举能让我们获取到扩展包提供的所有权限和角色的操作方法。
当然也可以在其他的模型中使用HasRoles,需要加上一句protected $guard_name = ‘web’;1
2
3
4
5
6
7
8
9
10
11use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Traits\HasRoles;
class Page extends Model
{
use HasRoles;
protected $guard_name = 'web'; // or whatever guard you want to use
// ...
}
2.数据库填充
创建实现初始化角色权限相关迁移文件:1
php artisan make:migration seed_roles_and_permissions_data
然后打开迁移文件,书写初始化权限和角色的代码:
注意:在填充数据之前更新以下spatie.permission.cache ,以避免缓存冲突的错误。可以手动重置1
php artisan cache:forget spatie.permission.cache
也可以在迁移文件中清除,示例如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class SeedRolesAndPermissionsData extends Migration
{
public function up()
{
// 清除缓存
app()['cache']->forget('spatie.permission.cache');
// 先创建权限
Permission::create(['name' => 'manage_contents']);
Permission::create(['name' => 'manage_users']);
Permission::create(['name' => 'edit_settings']);
// 创建站长角色,并赋予权限
$founder = Role::create(['name' => 'Founder']);
$founder->givePermissionTo('manage_contents');
$founder->givePermissionTo('manage_users');
$founder->givePermissionTo('edit_settings');
// 创建管理员角色,并赋予权限
$maintainer = Role::create(['name' => 'Maintainer']);
$maintainer->givePermissionTo('manage_contents');
}
public function down()
{
// 清除缓存
app()['cache']->forget('spatie.permission.cache');
// 清空所有数据表数据
$tableNames = config('permission.table_names');
Model::unguard();
DB::table($tableNames['role_has_permissions'])->delete();
DB::table($tableNames['model_has_roles'])->delete();
DB::table($tableNames['model_has_permissions'])->delete();
DB::table($tableNames['roles'])->delete();
DB::table($tableNames['permissions'])->delete();
Model::reguard();
}
}
3.初始化角色权限
为了测试方便起见,可以在用户填充数据后,为用户指派角色1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class UsersTableSeeder extends Seeder
{
public function run()
{
.
.
.
// 初始化用户角色,将 1 号用户指派为『站长』
$user->assignRole('Founder');
// 将 2 号用户指派为『管理员』
$user = User::find(2);
$user->assignRole('Maintainer');
}
}
然后刷新测试数据1
php artisan migrate:refresh --seed
内容管理权限
可以在策略中定义一个 before 方法,它会在策略中其他所有方法之前执行。这样可以实现统一授权的目的。
所有生成的授权策略,都会统一继承 App\Policies\Policy 基类,所以在基类中的before() 方法中加入
角色判断,就可以在所有的授权类中起到作用。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace App\Policies;
use Illuminate\Auth\Access\HandlesAuthorization;
class Policy
{
use HandlesAuthorization;
public function before($user, $ability)
{
// 如果用户拥有管理内容的权限的话,即授权通过
if ($user->can('manage_contents')) {
return true;
}
}
}
用法详解
1.角色分配给任意用户
1 | // 单个角色 |
2.角色可以从一个用户身上移除:
1 | $user->removeRole('writer'); |
3.检查用户角色
1 | // 是否是站长 |
4.检查权限
1 | // 检查用户是否有某个权限 |
5.直接给用户添加权限
1 | // 为用户添加『直接权限』 |