mistery23 / laravel-roles
处理Laravel中角色、权限和级别的强大包。
Requires
- php: >=7.3
- ext-pdo: *
- illuminate/support: ~5.8.0|^6.0
- laravel/framework: ~5.8.0|^6.0
- laravel/helpers: ^1.1
- mistery23/eloquent-flusher: ^2.0
- mistery23/eloquent-object-relations: ^1.2
- ramsey/uuid: ^3.8
- staudenmeir/laravel-adjacency-list: ^1.0
- webmozart/assert: 1.6.*
Requires (Dev)
- orchestra/testbench: ~3.0
- phpunit/phpunit: ^7.5
- roave/security-advisories: dev-master
- squizlabs/php_codesniffer: 3.*
This package is auto-updated.
Last update: 2020-11-03 11:51:51 UTC
README
目录
关于
一个强大的Laravel角色和权限处理包。支持Laravel 5.8和6.0。
特性
Laravel角色特性 |
---|
内置迁移,可发布和修改自己的迁移。 |
内置命令,可从配置中修改自己的种子数据。 |
带有级别和与用户、权限相关联的角色 |
与用户和级别相关联的权限 |
扩展角色和权限 |
软删除,包括完全恢复和销毁 |
可选的Api方法来管理角色和权限 |
许多配置选项 |
许多配置种子 |
所有可从.env扩展 |
安装
此包非常易于设置。只有几个步骤。
Composer
在终端中从您的项目根目录运行
Laravel 5.8及以上版本使用
composer require mistery23/laravel-roles
服务提供者
- Laravel 5.8及以上版本使用包自动发现功能,无需编辑
config/app.php
文件。
'providers' => [ ... /** * Third Party Service Providers... */ Mistery23\LaravelRoles\RolesServiceProvider::class, ],
发布所有资产
php artisan vendor:publish --tag=laravelroles
发布特定资产
php artisan vendor:publish --tag=laravelroles-config php artisan vendor:publish --tag=laravelroles-migrations
HasRoleAndPermission 特性和契约
-
包含
HasRoleAndPermission
特性,并在您的User
模型中实现HasRoleAndPermission
契约。下面是示例。 -
在您的
User
模型顶部包含use Mistery23\LaravelRoles\Traits\HasRoleAndPermission;
,并在实现HasRoleAndPermission
特性。下面是示例。
User
模型特性及契约示例
<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use Mistery23\LaravelRoles\Traits\HasRoleAndPermission; class User extends Authenticatable { use Notifiable; use HasRoleAndPermission; // rest of your model ... }
迁移和种子
本例使用Laravel默认的用户表。您应该已经有了用户表的迁移文件并且已迁移。
-
设置所需表
php artisan migrate
-
检查
config/roles-seed.php
文件。用于创建/更新角色和权限。 -
设置角色和权限
php artisan roles:gen
-
初始化一组权限和角色的种子。请在您的项目中实现将角色/权限分配给用户的逻辑。为此,您应使用完整的用例。
Mistery23\LaravelRoles\Model\UseCases\User\Attach\Role
Mistery23\LaravelRoles\Model\UseCases\User\Attach\Permission
角色已种植
属性 | 值 |
---|---|
名称 | 根 |
别名 | root |
描述 | 根角色 |
级别 | 100 |
属性 | 值 |
---|---|
名称 | 管理员 |
别名 | admin |
描述 | 管理员角色 |
级别 | 90 |
父级 | root |
权限 | portal.administrate |
属性 | 值 |
---|---|
名称 | 经理 |
别名 | manager |
描述 | 经理角色 |
级别 | 70 |
父级 | admin |
权限 | portal.user.manage, portal.user.manage.create |
属性 | 值 |
---|---|
名称 | 客户 |
别名 | client |
描述 | 客户角色 |
级别 | 50 |
权限已种植
属性 | 值 |
---|---|
名称 | 门户网站管理 |
别名 | portal.administrate |
描述 | 可以管理门户网站 |
属性 | 值 |
---|---|
名称 | 门户网站用户管理 |
别名 | portal.user.manage |
描述 | 可以管理用户 |
父级 | portal.administrate |
属性 | 值 |
---|---|
名称 | 门户网站用户创建 |
别名 | portal.user.manage.create |
描述 | 可以创建用户 |
父级 | portal.user.manage.create |
属性 | 值 |
---|---|
名称 | 门户网站客户 |
别名 | portal.use |
描述 | 可以使用门户网站 |
使用方法
创建角色
$command = new Mistery23\LaravelRoles\Model\UseCases\Role\Create\Command( 'Admin', 'admin', 90, 'Admin role' ); app(Mistery23\LaravelRoles\Model\UseCases\Role\Create::class)->handle($command);
附加、分离角色和权限
查看 Mistery23\LaravelRoles\Model\UseCases\...
以获取角色、权限和用户的全部操作。
检查角色
现在您可以检查用户是否有所需的角色。
if ($user->hasRole('admin')) { // you can pass an id or slug // }
您也可以这样做
if ($user->isAdmin()) { // }
当然,还有检查多个角色的方法
if ($user->hasRole(['admin', 'moderator'])) { /* | Or alternatively: | $user->hasRole('admin, moderator'), $user->hasRole('admin|moderator'), | $user->hasOneRole('admin, moderator'), $user->hasOneRole(['admin', 'moderator']), $user->hasOneRole('admin|moderator') */ // The user has at least one of the roles } if ($user->hasRole(['admin', 'moderator'], true)) { /* | Or alternatively: | $user->hasRole('admin, moderator', true), $user->hasRole('admin|moderator', true), | $user->hasAllRoles('admin, moderator'), $user->hasAllRoles(['admin', 'moderator']), $user->hasAllRoles('admin|moderator') */ // The user has all roles }
级别
当您创建角色时,有一个可选参数 level
。默认设置为 1
,但您可以重写它,然后您可以这样做
if ($user->level() > 4) { // }
如果用户有多个角色,则方法
level
返回最高级别。
Level
对权限继承也有重大影响。关于这一点稍后讨论。
检查权限
if ($user->hasPermission('create.users')) { // you can pass an id or slug // } if ($user->canDeleteUsers()) { // }
您可以使用与角色相同的方式检查多个权限。您可以使用额外的方法,如 hasOnePermission
或 hasAllPermissions
。
权限继承
级别较高的角色会从级别较低的角色的角色继承权限。
这里有这个 魔法
的例子
您有三个角色: user
、moderator
和 admin
。用户有读取文章的权限,版主可以管理评论,管理员可以创建文章。用户级别为1,版主级别2,管理员级别3。这意味着,版主和管理员也有阅读文章的权限,但管理员还可以管理评论。
如果您不想在您的应用程序中启用权限继承功能,只需在创建角色时忽略
level
参数即可。
实体检查
假设你有一篇文章,并想编辑它。这篇文章属于一个用户(文章表中有一个名为 user_id
的列)。
use App\Article; $article = Article::find(1); if ($user->allowed('edit.articles', $article)) { // $user->allowedEditArticles($article) // }
此条件检查当前用户是否是文章的所有者。如果不是,它将在之前创建的用户权限行中查找。
if ($user->allowed('edit.articles', $article, false)) { // now owner check is disabled // }
Blade 扩展
有四个 Blade 扩展。基本上,它是经典 if 语句的替代品。
@role('admin') // @if(Auth::check() && Auth::user()->hasRole('admin')) // user has admin role @endrole @permission('edit.articles') // @if(Auth::check() && Auth::user()->hasPermission('edit.articles')) // user has edit articles permissison @endpermission @level(2) // @if(Auth::check() && Auth::user()->level() >= 2) // user has level 2 or higher @endlevel @allowed('edit', $article) // @if(Auth::check() && Auth::user()->allowed('edit', $article)) // show edit button @endallowed @role('admin|moderator', true) // @if(Auth::check() && Auth::user()->hasRole('admin|moderator', true)) // user has admin and moderator role @else // something else @endrole
中间件
该软件包包含 VerifyRole
、VerifyPermission
和 VerifyLevel
中间件。中间件别名已在 \Mistery23\LaravelRoles\RolesServiceProvider
中注册。
现在你可以轻松保护你的路由。
Route::get('/', function () { // })->middleware('role:admin'); Route::get('/', function () { // })->middleware('permission:edit.articles'); Route::get('/', function () { // })->middleware('level:2'); // level >= 2 Route::get('/', function () { // })->middleware('role:admin', 'level:2'); // level >= 2 and Admin Route::group(['middleware' => ['role:admin']], function () { // });
如果出错,它将抛出 \Mistery23\LaravelRoles\App\Exceptions\RoleDeniedException
、\Mistery23\LaravelRoles\App\Exceptions\PermissionDeniedException
或 \Mistery23\LaravelRoles\App\Exceptions\LevelDeniedException
异常。
你可以在 app/Exceptions/Handler.php
文件中捕获这些异常并执行任何操作。
/** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { $userLevelCheck = $exception instanceof \Mistery23\LaravelRoles\App\Exceptions\RoleDeniedException || $exception instanceof \Mistery23\LaravelRoles\App\Exceptions\RoleDeniedException || $exception instanceof \Mistery23\LaravelRoles\App\Exceptions\PermissionDeniedException || $exception instanceof \Mistery23\LaravelRoles\App\Exceptions\LevelDeniedException; if ($userLevelCheck) { if ($request->expectsJson()) { return Response::json(array( 'error' => 403, 'message' => 'Unauthorized.' ), 403); } abort(403); } return parent::render($request, $exception); }
配置
- 你可以更改模型的连接、模型路径,还有一个方便的模拟功能。
- 有许多可配置的选项已扩展,可以通过
.env
文件变量进行配置。 - 由于这个原因,可能不需要直接编辑配置文件。
<?php return [ /* |-------------------------------------------------------------------------- | Package Connection |-------------------------------------------------------------------------- | | You can set a different database connection for this package. It will set | new connection for models Role and Permission. When this option is null, | it will connect to the main database, which is set up in database.php | */ 'connection' => env('ROLES_DATABASE_CONNECTION', null), 'usersTable' => env('ROLES_USERS_DATABASE_TABLE', 'user_users'), 'rolesTable' => env('ROLES_ROLES_DATABASE_TABLE', 'user_roles'), 'roleUserTable' => env('ROLES_ROLE_USER_DATABASE_TABLE', 'user_roles_users'), 'permissionsTable' => env('ROLES_PERMISSIONS_DATABASE_TABLE', 'user_permissions'), 'permissionsRoleTable' => env('ROLES_PERMISSION_ROLE_DATABASE_TABLE', 'user_permissions_roles'), 'permissionsUserTable' => env('ROLES_PERMISSION_USER_DATABASE_TABLE', 'user_permissions_users'), /* |-------------------------------------------------------------------------- | Models |-------------------------------------------------------------------------- | | If you want, you can replace default models from this package by models | you created. Have a look at `Mistery23\LaravelRoles\Model\Entity\Role\Role` model and | `Mistery23\LaravelRoles\Model\Entity\Permission\Permission` model. | */ 'models' => [ 'role' => env('ROLES_DEFAULT_ROLE_MODEL', Mistery23\LaravelRoles\Model\Entity\Role\Role::class), 'permission' => env('ROLES_DEFAULT_PERMISSION_MODEL', Mistery23\LaravelRoles\Model\Entity\Permission\Permission::class), 'permissionRole' => env('ROLES_DEFAULT_ROLE_PERMISSION_MODEL', Mistery23\LaravelRoles\Model\Entity\RolePermission::class), 'userRole' => env('ROLES_DEFAULT_ROLE_USER_MODEL', Mistery23\LaravelRoles\Model\Entity\RoleUser::class), 'userPermission' => env('ROLES_DEFAULT_PERMISSION_MODEL', Mistery23\LaravelRoles\Model\Entity\PermissionUser::class), 'defaultUser' => env('ROLES_DEFAULT_USER_MODEL', config('auth.providers.users.model')), ], 'dependencies' => [ 'userRepository' => env('USER_REPOSITORY', \App\Model\User\Entity\User\Repository\UserRepository::class), 'userQueries' => env('USER_QUERIES', \App\Model\User\Entity\User\Repository\UserQueries::class), ], 'defaultSeparator' => '.', /* |-------------------------------------------------------------------------- | Laravel Roles API Settings |-------------------------------------------------------------------------- | | This is the API for Laravel Roles to be able to CRUD them | easily and fast via an API. This is optional and is | not needed for your application. | */ 'rolesApiEnabled' => env('ROLES_API_ENABLED', true), // Enable `auth` middleware 'rolesAPIAuthEnabled' => env('ROLES_API_AUTH_ENABLED', true), // Enable Roles API middleware 'rolesAPIMiddlewareEnabled' => env('ROLES_API_MIDDLEWARE_ENABLED', true), // Optional Roles API Middleware 'rolesAPIMiddleware' => env('ROLES_API_MIDDLEWARE', 'role:admin'), ];
配置种子数据
<?php return [ 'users' => [ 'root' => [ 'email' => 'root@root.root', 'password' => 'secret', 'roles' => ['root'], ], 'admin' => [ 'email' => 'admin@admin.admin', 'password' => 'secret', 'roles' => ['admin'], ], 'manager' => [ 'email' => 'manager@manager.manager', 'password' => 'secret', 'roles' => ['manager'], ], 'client' => [ 'email' => 'client@client.client', 'password' => 'secret', 'roles' => ['client'], ], ], 'roles' => [ 'root' => [ 'name' => 'Root', 'description' => 'Root role', 'level' => 100, 'parent' => null, 'permissions' => [], ], 'admin' => [ 'name' => 'Admin', 'description' => 'Admin role', 'level' => 90, 'parent' => 'root', 'permissions' => ['portal.administrate'], ], 'manager' => [ 'name' => 'Manager', 'description' => 'Manager role', 'level' => 70, 'parent' => 'admin', 'permissions' => ['portal.user.manage', 'portal.user.manage.create'], ], 'client' => [ 'name' => 'Client', 'description' => 'Client role', 'level' => 50, 'parent' => null, 'permissions' => ['portal.use'], ], ], 'permissions' => [ 'portal.administrate' => [ 'name' => 'Portal administrate', 'description' => 'Can administrate portal', 'model' => null, 'parent' => null, ], 'portal.user.manage' => [ 'name' => 'Portal manage user', 'description' => 'Can manage user', 'model' => null, 'parent' => 'portal.administrate' ], 'portal.user.manage.create' => [ 'name' => 'Portal user create', 'description' => 'Can user create', 'model' => null, 'parent' => 'portal.user.manage.create' ], 'portal.use' => [ 'name' => 'Portal client', 'description' => 'Can use portal', 'model' => null, 'parent' => null ] ], ];
测试
docker-compose run php-cli vendor/bin/phpunit
环境文件
# Roles Default Models
ROLES_DEFAULT_USER_MODEL=App\User
ROLES_DEFAULT_ROLE_MODEL=Mistery23\LaravelRoles\Model\Entity\Role\Role
ROLES_DEFAULT_PERMISSION_MODEL=Mistery23\LaravelRoles\Model\Entity\Permission
ROLES_DEFAULT_ROLE_PERMISSION_MODEL=Mistery23\LaravelRoles\Model\Entity\RolePermission
ROLES_DEFAULT_ROLE_USER_MODEL=Mistery23\LaravelRoles\Model\Entity\RoleUser
ROLES_DEFAULT_PERMISSION_USER_MODEL=Mistery23\LaravelRoles\Model\Entity\PermissionUser
# Roles database information
ROLES_DATABASE_CONNECTION=null
ROLES_USERS_DATABASE_TABLE=user_users
ROLES_ROLES_DATABASE_TABLE=user_roles
ROLES_ROLE_USER_DATABASE_TABLE=user_roles_users
ROLES_PERMISSIONS_DATABASE_TABLE=user_permissions
ROLES_PERMISSION_ROLE_DATABASE_TABLE=user_permissions_roles
ROLES_PERMISSION_USER_DATABASE_TABLE=user_permissions_users
# Dependencies
USER_REPOSITORY=App\Model\User\Repository\UserRepository
USER_QUERIES=App\Model\User\Repository\UserQueries
可选 API 路由
| | POST | permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@store | auth:api,role:admin |
| | GET|HEAD | permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@index | auth:api,role:admin |
| | PUT | permissions/{permissionId} | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@edit | auth:api,role:admin |
| | DELETE | permissions/{permissionId} | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@destroy | auth:api,role:admin |
| | PATCH | permissions/{permissionId}/do-child | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@doChild | auth:api,role:admin |
| | PATCH | permissions/{permissionId}/do-root | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\PermissionsController@doRoot | auth:api,role:admin |
| | GET|HEAD | roles | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@index | auth:api,role:admin |
| | POST | roles | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@store | auth:api,role:admin |
| | PUT | roles/{roleId} | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@edit | auth:api,role:admin |
| | DELETE | roles/{roleId} | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@destroy | auth:api,role:admin |
| | POST | roles/{roleId}/copy | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@copy | auth:api,role:admin |
| | PATCH | roles/{roleId}/do-child | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@doChild | auth:api,role:admin |
| | PATCH | roles/{roleId}/do-root | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@doRoot | auth:api,role:admin |
| | DELETE | roles/{roleId}/permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@detachPermission | auth:api,role:admin |
| | POST | roles/{roleId}/permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@attachPermission | auth:api,role:admin |
| | GET|HEAD | roles/{roleId}/permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\RolesController@withPermissions | auth:api,role:admin |
| | POST | users/{userId}/permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\UsersController@attachPermission | auth:api,role:admin |
| | DELETE | users/{userId}/permissions | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\UsersController@detachPermission | auth:api,role:admin |
| | POST | users/{userId}/roles | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\UsersController@attachRole | auth:api,role:admin |
| | DELETE | users/{userId}/roles | laravelroles:: | Mistery23\LaravelRoles\App\Http\Controllers\Api\UsersController@detachRole | auth:api,role:admin |
文件树
|-- .env.example |-- .gitignore |-- LICENSE.MD |-- README.MD |-- composer.json |-- config | |-- roles-seed.php | `-- roles.php |-- database | `-- migrations | |-- 2016_01_15_105324_create_roles_table.php | |-- 2016_01_15_114412_create_role_user_table.php | |-- 2016_01_26_115212_create_permissions_table.php | |-- 2016_01_26_115523_create_permission_role_table.php | `-- 2016_02_09_132439_create_permission_user_table.php |-- docker | `-- development | |-- php-cli | | `-- default.ini | `-- php-cli.docker |-- docker-compose.yml |-- phpunit.xml |-- resources | `-- lang | `-- en | `-- laravelroles.php |-- routes | `-- api.php `-- src |-- Console | `-- Commands | `-- Roles.php |-- Contracts | |-- HasRoleAndPermission.php | |-- PermissionHasRelations.php | |-- RoleHasRelations.php | |-- UserQueriesInterface.php | `-- UserRepositoryInterface.php |-- Exceptions | |-- AccessDeniedException.php | |-- LevelDeniedException.php | |-- PermissionDeniedException.php | `-- RoleDeniedException.php |-- Http | |-- Controllers | | `-- Api | | |-- AbstractController.php | | |-- PermissionsController.php | | |-- RolesController.php | | `-- UsersController.php | |-- Middleware | | |-- VerifyLevel.php | | |-- VerifyPermission.php | | `-- VerifyRole.php | `-- Requests | |-- Permission | | |-- CreatePermissionRequest.php | | |-- DoChildPermissionRequest.php | | `-- UpdatePermissionRequest.php | |-- Role | | |-- AttachPermissionRequest.php | | |-- CopyRoleRequest.php | | |-- CreateRoleRequest.php | | |-- DetachPermissionRequest.php | | |-- DoChildRoleRequest.php | | `-- UpdateRoleRequest.php | `-- User | |-- AttachPermissionRequest.php | |-- AttachRoleRequest.php | |-- DetachPermissionRequest.php | `-- DetachRoleRequest.php |-- Model | |-- Entity | | |-- Permission | | | |-- Permission.php | | | `-- Repository | | | |-- PermissionRepository.php | | | `-- PermissionRepositoryInterface.php | | |-- PermissionUser.php | | |-- Role | | | |-- Repository | | | | |-- RoleRepository.php | | | | `-- RoleRepositoryInterface.php | | | `-- Role.php | | |-- RolePermission.php | | `-- RoleUser.php | |-- ReadModels | | |-- PermissionQueries.php | | |-- PermissionQueriesInterface.php | | |-- RoleQueries.php | | `-- RoleQueriesInterface.php | |-- UseCases | | |-- Permission | | | |-- Create | | | | |-- Command.php | | | | `-- Handler.php | | | |-- DoChild | | | | |-- Command.php | | | | `-- Handler.php | | | |-- DoRoot | | | | |-- Command.php | | | | `-- Handler.php | | | |-- Edit | | | | |-- Command.php | | | | `-- Handler.php | | | `-- Remove | | | |-- Command.php | | | `-- Handler.php | | |-- Role | | | |-- Attach | | | | `-- Permission | | | | |-- Command.php | | | | `-- Handler.php | | | |-- Copy | | | | |-- Command.php | | | | `-- Handler.php | | | |-- Create | | | | |-- Command.php | | | | `-- Handler.php | | | |-- Detach | | | | `-- Permission | | | | |-- Command.php | | | | `-- Handler.php | | | |-- DoChild | | | | |-- Command.php | | | | `-- Handler.php | | | |-- DoRoot | | | | |-- Command.php | | | | `-- Handler.php | | | |-- Edit | | | | |-- Command.php | | | | `-- Handler.php | | | `-- Remove | | | |-- Command.php | | | `-- Handler.php | | `-- User | | |-- Attach | | | |-- Permission | | | | |-- Command.php | | | | `-- Handler.php | | | `-- Role | | | |-- Command.php | | | `-- Handler.php | | `-- Detach | | |-- Permission | | | |-- Command.php | | | `-- Handler.php | | `-- Role | | |-- Command.php | | `-- Handler.php | `-- Utils | |-- Splitter.php | `-- SplitterInterface.php |-- RolesFacade.php |-- RolesServiceProvider.php `-- Traits |-- DatabaseTraits.php |-- HasRoleAndPermission.php |-- PermissionHasRelations.php `-- RoleHasRelations.php
- 可以使用 brew 安装树命令:
brew install tree
- 使用命令
tree -a -I '.idea|.git|node_modules|vendor|storage|tests|composer.lock'
生成文件树
许可
此软件包是免费软件,根据 MIT 许可协议 分发。请享受!