一、定义

菜单是包含权限的功能的,权限的构成很简单,就是名称还有URI,URI是唯一标示你可以操作的动作,例如 admin/access/index代表你可以操作权限列表页面。

1.1 特点:

  1. 权限URI可以理解为一个权限前缀,也就是如果你授权了 admin/access/index 你将同时拥有 admin/access/index/* 权限,* 代表所有字符。建议同一个页面下涉及到的权限都有同一个URI前缀。
  2. 父菜单无权限化、因为父菜单是在权限分配中是默认分配出去的,所以需要将父菜单用一个无效权限处理。例如配置管理我们使用的 admin/setting/none而不是 admin/setting这样既可以显示出父菜单,有不会因为父菜单把未授权的子菜单匹配出来。
  3. 权限最多三级,系统限制权限的等级最多为三级。

二、添加菜单/权限

目前添加权限的途径有两个,一个是模块安装的时候添加,一个是在管理后台直接添加权限。

2.1 模块安装添加菜单/权限

在每个模块的安装目录下,都会有一个 Install文件夹,下面有一个access.php 文件。这个文件有是一个多维数组结构,需要注意权限的层级最多只能是三级。

  1. <?php
  2. declare(strict_types=1);
  3. return [
  4. [
  5. 'parent_access_id' => 0,
  6. 'access_name' => '概览',
  7. 'uri' => 'admin/main/index', //权限访问的URI
  8. 'params' => '', //访问参数,一般菜单会配置
  9. 'sort' => 100,//排序,约小越靠前
  10. 'is_menu' => 1, //是否菜单1是0否
  11. 'menu_icon' => 'el-icon-data-analysis', //菜单显示的图标,一般一级菜单才需要
  12. ],
  13. [
  14. 'parent_access_id' => 0,
  15. 'access_name' => '设置',
  16. 'uri' => 'admin/none',
  17. 'params' => '',
  18. 'sort' => 100,
  19. 'is_menu' => 1,
  20. 'menu_icon' => 'el-icon-setting',
  21. 'children' => [
  22. [
  23. 'access_name' => '菜单与权限',
  24. 'uri' => 'admin/access/index',
  25. 'sort' => 100,
  26. 'is_menu' => 1,
  27. 'children' => [
  28. [
  29. 'access_name' => '新增/编辑菜单/权限',
  30. 'uri' => 'admin/access/edit',
  31. 'sort' => 100,
  32. 'is_menu' => 0,
  33. ]
  34. ]
  35. ],
  36. ]
  37. ],
  38. ];

2.2 管理后台添加

直接在 设置>权限与菜单页面中添加即可,如果是一级菜单可以选择系统自动的图标。
image.png image.png

三、权限验证

管理后台权限校验主要是通过 AccessService::getInstance()->checkAccess($path) 进行验证。验证方式主要是通过URI匹配的方式,主要能够匹配URI前缀就算权限验证通过。

  1. public function checkAccess(string $path): bool
  2. {
  3. $role_id = AdminUserService::getInstance()
  4. ->getAdminUserRoleId();
  5. if ($role_id === 0) {
  6. return true;
  7. }
  8. $role_access_list = $this->getRoleAccessList($role_id);
  9. foreach ($role_access_list as $item) {
  10. if (Str::is($item, $path) || Str::is($item . '/*', $path)) {
  11. return true;
  12. }
  13. }
  14. return false;
  15. }

四、权限白名单

权限白名单可以在config/autoload/access.php 的 not_auth 进行配置,该配置下的权限所有管理都拥有。