1、下载laravel框架
composer create-project --prefer-dist laravel/laravel laravel "5.8.*"
备注:--prefer-dist 压缩版
2、安装
composer require spatie/laravel-permission^3.18.0
3、发布
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePermissionTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
});
Schema::create($tableNames['roles'], function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames) {
$table->unsignedBigInteger('permission_id');
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'user_has_permissions_model_id_model_type_index');
$table->foreign('permission_id')
->references('id')
->on($tableNames['permissions'])
->onDelete('cascade');
$table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'],
'user_has_permissions_permission_model_type_primary');
});
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) {
$table->unsignedBigInteger('role_id');
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'user_has_roles_model_id_model_type_index');
$table->foreign('role_id')
->references('id')
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'],
'user_has_roles_role_model_type_primary');
});
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
$table->unsignedBigInteger('permission_id');
$table->unsignedBigInteger('role_id');
$table->foreign('permission_id')
->references('id')
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary(['permission_id', 'role_id'], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['user_has_roles']);
Schema::drop($tableNames['user_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
}
4、生成数据库
php artisan migrate
5、生成配置文件
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
<?php
return [
'models' => [
/*
* When using the "HasPermissions" trait from this package, we need to know which
* Eloquent model should be used to retrieve your permissions. Of course, it
* is often just the "Permission" model but you may use whatever you like.
*
* The model you want to use as a Permission model needs to implement the
* `Spatie\Permission\Contracts\Permission` contract.
*/
'permission' => Spatie\Permission\Models\Permission::class,
/*
* When using the "HasRoles" trait from this package, we need to know which
* Eloquent model should be used to retrieve your roles. Of course, it
* is often just the "Role" model but you may use whatever you like.
*
* The model you want to use as a Role model needs to implement the
* `Spatie\Permission\Contracts\Role` contract.
*/
'role' => Spatie\Permission\Models\Role::class,
],
'table_names' => [
/*
* When using the "HasRoles" trait from this package, we need to know which
* table should be used to retrieve your roles. We have chosen a basic
* default value but you may easily change it to any table you like.
*/
'roles' => 'roles',
/*
* When using the "HasPermissions" trait from this package, we need to know which
* table should be used to retrieve your permissions. We have chosen a basic
* default value but you may easily change it to any table you like.
*/
'permissions' => 'permissions',
/*
* When using the "HasPermissions" trait from this package, we need to know which
* table should be used to retrieve your models permissions. We have chosen a
* basic default value but you may easily change it to any table you like.
*/
'model_has_permissions' => 'user_has_permissions',
/*
* When using the "HasRoles" trait from this package, we need to know which
* table should be used to retrieve your models roles. We have chosen a
* basic default value but you may easily change it to any table you like.
*/
'model_has_roles' => 'user_has_roles',
/*
* When using the "HasRoles" trait from this package, we need to know which
* table should be used to retrieve your roles permissions. We have chosen a
* basic default value but you may easily change it to any table you like.
*/
'role_has_permissions' => 'role_has_permissions',
],
'column_names' => [
/*
* Change this if you want to name the related model primary key other than
* `model_id`.
*
* For example, this would be nice if your primary keys are all UUIDs. In
* that case, name this `model_uuid`.
*/
'model_morph_key' => 'model_id',
],
/*
* When set to true, the required permission names are added to the exception
* message. This could be considered an information leak in some contexts, so
* the default setting is false here for optimum safety.
*/
'display_permission_in_exception' => false,
/*
* When set to true, the required role names are added to the exception
* message. This could be considered an information leak in some contexts, so
* the default setting is false here for optimum safety.
*/
'display_role_in_exception' => false,
/*
* By default wildcard permission lookups are disabled.
*/
'enable_wildcard_permission' => false,
'cache' => [
/*
* By default all permissions are cached for 24 hours to speed up performance.
* When permissions or roles are updated the cache is flushed automatically.
*/
'expiration_time' => \DateInterval::createFromDateString('24 hours'),
/*
* The cache key used to store all permissions.
*/
'key' => 'spatie.permission.cache',
/*
* When checking for a permission against a model by passing a Permission
* instance to the check, this key determines what attribute on the
* Permissions model is used to cache against.
*
* Ideally, this should match your preferred way of checking permissions, eg:
* `$user->can('view-posts')` would be 'name'.
*/
'model_key' => 'name',
/*
* You may optionally indicate a specific cache driver to use for permission and
* role caching using any of the `store` drivers listed in the cache.php config
* file. Using 'default' here means to use the `default` set in cache.php.
*/
'store' => 'default',
],
];
6、操作及使用
配置模型如图:
路由:
控制器:
<?php
namespace App\Http\Controllers;
use App\Http\Models\User;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class IndexController extends Controller
{
/**
* 权限测试
* @author: qitao
* @date: 2021/12/16
*/
public function add()
{
// 增加角色
$role = Role::create(['name' => 'manager']);
// 增加权限
$permission = Permission::create(['name' => 'edit']);
$permission = Permission::create(['name' => 'add']);
// 角色关联权限
$role->givePermissionTo('edit');
$role->givePermissionTo('edit', 'delete');
$permission->assignRole($role);
$role->syncPermissions($permission);
$permission->syncRoles($role);
dd(1111);
// 获取用户
$user = User::where('id', 1)->first();
// 用户赋予角色
$user->assignRole('writer');
// 用户赋予权限
$user->givePermissionTo(['add', 'edit']);
// 获取用户所有角色名称 返回一个集合(collection)
$roles = $user->getRoleNames();
dd($roles);
// 获取直接分配给用户的所有权限
$user = User::where('id', 1)->first();
$permissions = $user->permissions;
// 获取用户的所有权限,包括直接分配的、通过角色继承的,或者两者全部
$permissions = $user->getDirectPermissions();
$permissions = $user->getPermissionsViaRoles()->toArray();
dd($permissions);
$users = User::role('writer')->get(); // 返回拥有 'writer' 角色的用户
$users = User::permission('edit')->get(); // 返回拥有特定权限的用户(包括直接分配的和通过角色继承的)
dd($users->toArray());
// 检测用户是否有某个权限
$user = User::where('id', 1)->first();
$rv0 = $user->hasPermissionTo('list');
// 或者传入权限的 id
$rv1 = $user->hasPermissionTo(1);
$rv2 = $user->hasPermissionTo(Permission::find(5)->id ?? 1);
dd($rv0,$rv1, $rv2);
// 判断用户是否具有一组权限中的任意一个或全部:
$user = User::find(1);
$re1 = $user->hasAnyPermission(['edit', 'add']);
$re2 = $user->hasAllPermissions(['edit', 'delete', 'list']);
// 同样可以仅传入权限的 id
$re3 = $user->hasAnyPermission(['edit', 1, 5]);
dd($re1, $re2, $re3);
// 检测用户是否具有特定角色,一个、任意或全部:
$user = User::find(1);
$rr1 = $user->hasRole('writer');
$rr2 = $user->hasAnyRole(Role::all());
$rr3 = $user->hasAllRoles(Role::all());
dd($rr1, $rr2, $rr3);
}
}
模板中判断角色是否拥有权限:
测试一个特定的角色:
@role('writer')
I am a writer!
@else
I am not a writer...
@endrole
或
@hasrole('writer')
I am a writer!
@else
I am not a writer...
@endhasrole
使用 Laravel 原生的 @can 指令来检查用户是否具有某种权限。
@can('edit articles')
//
@endcan