基于 ThinkPHP 的 API 项目实战:权限控制

最近开发的移动 App 服务端 api 选用ThinkPHP来写,现需要针对不同用户进行获取数据时的权限控制,其中用户的授权信息由公司的 ERP 系统来维护,这里记录下实现过程。

权限数据结构

用到的相关表有:功能权限、用户权限、用户组权限,其中后两个表已经合并为一个视图方便查询。

20190418162321695.png

获取用户权限保存到 Array

为了方便在各控制器中调用,在 common.php 中定义了 getPerms() 方法用于获取当前用户所有权限。
同时获取权限数据后保存到 redis 缓存 1 小时,当然要考虑在 ERP 中修改权限后清空一下缓存。

/**
 * 获取用户权限列表
 */
function getPerms()
{
    try {
        $userGuid = input('_userInfo')['UserGuid'];

        //查询缓存
        $cache = Cache::store('redis')->get('user:perms:' . $userGuid, '');

        //缓存不存在查询数据库
        if ($cache == '') {
            $sql1 = "select concat(isnull(RightValue1,0),',',isnull(RightValue2,0),',',isnull(RightValue3,0)) as Value from SYS_UserFuncRight_View a 
                      where a.FuncFrameGuid in (select Guid from SYS_FuncFrame where ModuleId='ADM.FMS') and UserGuid=:UserGuid";
            $sql2 = "select concat(isnull(RightInfo1_EN,''),',',isnull(RightInfo2_EN,''),',',isnull(RightInfo3_EN,'')) as Name from SYS_FuncFrame where ModuleId='ADM.FMS'";

            $permsValue = Db::connect('db_LTGROUP')->query($sql1, ['UserGuid' => $userGuid]);
            $permsName  = Db::connect('db_LTGROUP')->query($sql2);

            $arrayName = explode(",", $permsName[0]['Name']); //逗号分隔的权限名称字符串
            $perms     = []; //保存最终权限的数组
            foreach ($permsValue as $item) {
                $arrayValue = explode(",", $item['Value']); //授权值,有权限为1,无权限为0
                $perm       = [];
                foreach ($arrayValue as $key => $value) {
                    if ($value) $perm[] = $arrayName[$key]; //有权限则将名称加到[临时权限数组]中
                }

                $perms = array_merge($perm, $perms); //将[临时权限数组]合并到[权限最终数组]
            }

            $result = $perms;
            Cache::store('redis')->set('user:perms:' . $userGuid, json_encode($result), 3600); //写入缓存,有效期3600秒=1小时
        } else {
            $result = json_decode($cache);
        }
    } catch (\think\Exception $e) {
        Log::record('查询用户权限时出错。' . $e->getMessage());
        $result = [];
    }

    return $result;
}

/**
 * 是否拥有指定权限
 * @param $perm : 要查询的权限名
 * @return bool 是否拥有
 */
function hasPerm($perm)
{
    $perms = getPerms();
    return array_key_exists($perm, $perms);
}

权限的使用

在控制器相关业务方法中就可以判断用户是否有某项权限,进而进行数据控制。如这里有WorkReportQueryAll这项权限可以查询所有单据,否则只能查询本人的单据。

    //获取工作汇报列表
    public function getList()
    {
        //参数检查
        $begindate = input('begindate');
        $enddate   = input('enddate');
        if (!valid_date($begindate) || !valid_date($enddate)) {
            return error('日期参数有误');
        }

        //用户名
        $userName = input('username', '%');

        //权限控制:没有权限只能查询自己的单据
        if (!hasPerm('WorkReportQueryAll')) {
            $userName = input('_userInfo')['UserName'];
        }

        $pagesize  = input('pagesize /d', 10);
        $pageindex = input('pageindex /d', 1);

        //获取数据....
        $data = ...

        return success($data);
    }

刚开始学习 PHP,如有错误之处望指正。

最后修改:2019 年 04 月 18 日 04 : 43 PM
如果觉得我的文章对你有用,请随意赞赏

1 条评论

  1. 冬哩

    逛逛

发表评论