[BD]权限系统的实现

71 阅读2分钟

官方介绍: 链接

之前每次请求都会有一个index的请求发过去, 以为是重复了, 现在才知道是获取菜单节点用的

image.png

1.控制器和请求地址,代码
app\admin\controller\Index.php 控制器地址
http://localhost:8000/admin/index/index 请求地址
public function index()
{
    $adminInfo          = $this->auth->getInfo();
    $adminInfo['super'] = $this->auth->isSuperAdmin();
    unset($adminInfo['token'], $adminInfo['refreshToken']);

    $menus = $this->auth->getMenus(); // -这里就是获取权限节点
    if (!$menus) {
        $this->error(__('No background menu, please contact super administrator!'));
    }
    $this->success('', [
        'adminInfo'  => $adminInfo,
        'menus'      => $menus,
        'siteConfig' => [
            'siteName' => get_sys_config('site_name'),
            'version'  => get_sys_config('version'),
            'cdnUrl'   => full_url(),
            'apiUrl'   => Config::get('buildadmin.api_url'),
            'upload'   => get_upload_config(),
        ],
        'terminal'   => [
            'installServicePort' => Config::get('terminal.install_service_port'),
            'npmPackageManager'  => Config::get('terminal.npm_package_manager'),
        ]
    ]);
}
2.获取权限节点的流程 $this->auth->getMenus();
app\admin\library\Auth.php
public function getMenus(int $uid = 0): array
{
    return parent::getMenus($uid ?: $this->id);
}

最后获取权限节点的地方

extend\ba\Auth.php
// 1.获取菜单规则列表
public function getMenus(int $uid): array
{
    if (!$this->rules) {
        $this->getRuleList($uid);  // --
    }
    if (!$this->rules) {
        return [];
    }
    foreach ($this->rules as $rule) {
        $this->childrens[$rule['pid']][] = $rule;
    }
    if (!isset($this->childrens[0])) {
        return [];
    }
    return $this->getChildren($this->childrens[0]);
}

// 2. 获得权限规则列表
public function getRuleList(int $uid): array
    {
        // 静态保存所有用户验证通过的权限列表
        static $ruleList = [];
        if (isset($ruleList[$uid])) {
            return $ruleList[$uid];
        }

        // 读取用户规则节点
        $ids = $this->getRuleIds($uid); // --
        if (empty($ids)) {
            $ruleList[$uid] = [];
            return [];
        }

        $where[] = ['status', '=', '1'];
        // 如果没有 * 则只获取用户拥有的规则
        if (!in_array('*', $ids)) {
            $where[] = ['id', 'in', $ids];
        }
        // 读取用户组所有权限规则
        $this->rules = Db::name($this->config['auth_rule'])
            ->withoutField(['remark', 'status', 'weigh', 'updatetime', 'createtime'])
            ->where($where)
            ->order('weigh desc,id asc')
            ->select()->toArray();
        // 用户规则
        $rules = [];
        if (in_array('*', $ids)) {
            $rules[] = "*";
        }
        foreach ($this->rules as $key => $rule) {
            $rules[$rule['id']] = strtolower($rule['name']);
            if (isset($rule['keepalive']) && $rule['keepalive']) {
                $this->rules[$key]['keepalive'] = $rule['name'];
            }
        }
        
        $ruleList[$uid] = $rules;
        return array_unique($rules);
 }
 
 // 3.获取权限规则ids
public function getRuleIds(int $uid): array
{
    // 用户的组别和规则ID
    $groups = $this->getGroups($uid); // --
    $ids    = [];
    foreach ($groups as $g) {
        $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
    }
    return array_unique($ids);
}

// 4.获取用户所有分组和对应权限规则
public function getGroups(int $uid): array
{
    static $groups = [];
    if (isset($groups[$uid])) {
        return $groups[$uid];
    }

    if ($this->config['auth_group_access']) {
        $userGroups = Db::name($this->config['auth_group_access'])
            ->alias('aga')
            ->join($this->config['auth_group'] . ' ag', 'aga.group_id = ag.id', 'LEFT')
            ->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules')
            ->where("aga.uid='$uid' and ag.status='1'")
            ->select()->toArray();
    } else {
        $userGroups = Db::name('user')
            ->alias('u')
            ->join($this->config['auth_group'] . ' ag', 'u.group_id = ag.id', 'LEFT')
            ->field('u.id as uid,u.group_id,ag.id,ag.name,ag.rules')
            ->where("u.id='$uid' and ag.status='1'")
            ->select()->toArray();
    }

    $groups[$uid] = $userGroups ?: [];
    return $groups[$uid];
}
3.最后接口返回的结果
{
    "code": 1,
    "msg": "",
    "time": 1684745603,
    "data": {
        "adminInfo": {
            "id": 1,
            "username": "admin",
            "nickname": "Admin",
            "avatar": "http://localhost:8000/static/images/avatar.png",
            "lastlogintime": "2023-05-22 16:53:23",
            "super": true
        },
        "menus": [
            {
                "id": 1,
                "pid": 0,
                "type": "menu",
                "title": "控制台",
                "name": "dashboard/dashboard",
                "path": "dashboard",
                "icon": "fa fa-dashboard",
                "menu_type": "tab",
                "url": "",
                "component": "/src/views/backend/dashboard.vue",
                "keepalive": "dashboard/dashboard",
                "extend": "none"
            },
            // 省略
            {
                "id": 171,
                "pid": 0,
                "type": "menu",
                "title": "用户管理",
                "name": "adminUser",
                "path": "adminUser",
                "icon": "el-icon-User",
                "menu_type": "tab",
                "url": "",
                "component": "/src/views/backend/adminUser/index.vue",
                "keepalive": 0,
                "extend": "none",
                "children": [
                    {
                        "id": 172,
                        "pid": 171,
                        "type": "button",
                        "title": "查看",
                        "name": "adminUser/index",
                        "path": "",
                        "icon": "",
                        "menu_type": null,
                        "url": "",
                        "component": "",
                        "keepalive": 0,
                        "extend": "none"
                    },  
                    {
                        "id": 179,
                        "pid": 171,
                        "type": "button",
                        "title": "获取用户组",
                        "name": "AdminUser/getUserGroup",
                        "path": "",
                        "icon": "el-icon-Minus",
                        "menu_type": "tab",
                        "url": "",
                        "component": "",
                        "keepalive": 0,
                        "extend": "none"
                    },
                    {
                        "id": 180,
                        "pid": 171,
                        "type": "button",
                        "title": "获取可选用户列表",
                        "name": "AdminUser/getPidUser",
                        "path": "",
                        "icon": "el-icon-Minus",
                        "menu_type": "tab",
                        "url": "",
                        "component": "",
                        "keepalive": 0,
                        "extend": "none"
                    }
                ]
            }
        ],
        "siteConfig": {
            "siteName": "小工具",
            "version": "v1.0.0",
            "cdnUrl": "http://localhost:8000",
            "apiUrl": "https://buildadmin.com",
            "upload": {
                "maxsize": 10485760,
                "savename": "/storage/{topic}/{year}{mon}{day}/{filesha1}{.suffix}",
                "mimetype": "jpg,png,bmp,jpeg,gif,webp,zip,rar,xls,xlsx,doc,docx,wav,mp4,mp3,txt",
                "mode": "local"
            }
        },
        "terminal": {
            "installServicePort": "8000",
            "npmPackageManager": "pnpm"
        }
    }
}