搜索中心
搜索中心 搜索快照

模块入门开发教程 - 后台权限管理

权限校验原理

后台权限管理统一在 ModStart\Admin\Middleware\AuthMiddleware.php 管理,匹配规则如下:

  • ① 根据访问路径拼接权限标识,如 \Module\Aaa\Admin\Controller\BbbController@ccc
  • ② 如果管理员权限标识列表中包含第 ① 步拼接的权限标识,则校验权限成功,否则进行第 ③ 步
  • ③ 如果当前控制器定义了静态变量 $PermitMethodMap,对权限标识进行转换,转换表如下
    • currentMethod => checkMethod 使用 当前 Controller 的 checkMethod 检查权限
    • currentMethod => controller@method 使用 Controller@method 检查权限
    • currentMethod => @rule 使用 rule 检查权限
    • currentMethod => * 忽略匹配不到时的权限检查
    • * => * 本 Controller 的所有方法匹配不到时忽略权限检查
  • ④ 查找管理员权限标识中是否拥有权限标识,如果有则校验权限成功,否则权限校验失败

权限标识定义方法

在后台导航菜单定义时,默认会 url 作为权限校验标识

// ...
[
  'title' => '二级菜单',
  'url' => '\Module\Xxx\Admin\Controller\XxxController@index',
  // 增加隐藏菜单的参数
  'hide' => true,
]
// ...

也可自定义权限标识

// ...
[
  'title' => '二级菜单',
  'url' => '\Module\Xxx\Admin\Controller\XxxController@index',
  'rule' => 'MyCustomRule',
  'hide' => true,
]
// ...

在代码可以使用以下方法判断是否包含某个权限

// 判断是否包含某个权限
\ModStart\Admin\Auth\AdminPermission::permit('\Module\Xxx\Admin\Controller\XxxController@index');
\ModStart\Admin\Auth\AdminPermission::permit('MyCustomRule');

管理员权限标识获取方法

使用了RBAC标准授权:

用户表(admin_user) ↔ 角色关联表(admin_user_role) ↔ 角色表(admin_role) ↔ 角色权限表(admin_role_rule)

用户登录后可通过如下方法获取用户角色标识列表

// 获取管理员所有权限标识
Session::get('_adminRules',[])
// 判断是否包含某个权限
\ModStart\Admin\Auth\AdminPermission::permit('Xxx');

更细粒度的权限控制

根据 权限校验原理 可以看到,默认是基于 Controller 粒度的权限校验。 如果需要对页面的更细粒度的权限控制,需要在 ModuleServiceProvider中注册更多的权限校验规则。

以独立控制后台增删改查权限为例,可以在 ModuleServiceProvider 中注册如下规则,在菜单定义时使用 hide 参数隐藏菜单,但是权限控制出现在角色配置上。

// 通过设置 hide 为 true,隐藏菜单,但是权限控制出现在角色上。
AdminMenu::register(function () {
    return [
        [
            'title' => '内容管理',
            'icon' => 'file',
            'sort' => 150,
            'children' => [
                [
                    'title' => '内容列表',
                    'url' => '\ModStart\Admin\Controller\AdminRoleController@index',
                ],
                [
                    'title' => '内容添加权限',
                    'rule'  => '\ModStart\Admin\Controller\AdminRoleController@add',
                    'hide' => true,
                ],
                [
                    'title' => '内容编辑权限',
                    'rule'  => '\ModStart\Admin\Controller\AdminRoleController@edit',
                    'hide' => true,
                ],
                [
                    'title' => '内容删除权限',
                    'rule'  => '\ModStart\Admin\Controller\AdminRoleController@delete',
                    'hide' => true,
                ],
                [
                    'title' => '内容查看权限',
                    'rule'  => '\ModStart\Admin\Controller\AdminRoleController@show',
                    'hide' => true,
                ],
            ],
        ],
    ];
});

随后再 Grid 中设置操作:

$grid->canAdd(AdminPermission::permit('\ModStart\Admin\Controller\AdminRoleController@add'))
     ->canEdit(AdminPermission::permit('\ModStart\Admin\Controller\AdminRoleController@edit'))
     ->canDelete(AdminPermission::permit('\ModStart\Admin\Controller\AdminRoleController@delete'))
     ->canShow(AdminPermission::permit('\ModStart\Admin\Controller\AdminRoleController@show'));

如果需要更详细的控制每一行是否显示某个操作,可以需要定义每行的操作:

$grid->hookItemOperateRendering(function (ItemOperate $itemOperate) {
    // 当前行记录
    $item = $itemOperate->item();
    // 判断是否可编辑
    $itemOperate->canEdit( $item->adminUserId === Admin::id() );
});

同时,需要在 edit 方法中增加权限校验:

public function edit()
{
    $record = ModuleUtil::get('xxx', CRUDUtil::id());
    // 判断是否可编辑
    BizException::throwsIf('无权限', $record['adminUserId'] != Admin::id());
}
查看原文
QQ
微信