thinkphp5 权限控制 Hook

* 项目地址:

https://gitee.com/wukongcrm/72crm

 

* 数据库结构:

 

** 权限规则表

CREATE TABLE `5kcrm_admin_rule` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `types` tinyint(2) NOT NULL DEFAULT '0' COMMENT '0系统设置1工作台2客户管理3项目管理4人力资源5财务管理6商业智能',
  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '定义',
  `level` tinyint(5) NOT NULL DEFAULT '0' COMMENT '级别。1模块,2控制器,3操作',
  `pid` int(11) DEFAULT '0' COMMENT '父id,默认0',
  `status` tinyint(3) DEFAULT '1' COMMENT '状态,1启用,0禁用',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=97 DEFAULT CHARSET=utf8 COMMENT='权限规则表';

INSERT INTO `zkt_crm`.`5kcrm_admin_rule` (`id`, `types`, `title`, `name`, `level`, `pid`, `status`) VALUES ('1', '2', '全部', 'crm', '1', '0', '1');

  id          type   title                          name             level        pid      status

根据模块名(level=1),控制器名(level=2),方法名(level=3)

用户组表:

CREATE TABLE `5kcrm_admin_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` tinyint(4) NOT NULL COMMENT '分类1管理角色2客户管理角色3人事角色4财务角色5项目角色0自定义角色',
  `title` varchar(100) NOT NULL COMMENT '名称',
  `rules` varchar(2000) NOT NULL DEFAULT '' COMMENT '规则',
  `remark` varchar(100) NOT NULL DEFAULT '' COMMENT '备注',
  `status` tinyint(3) DEFAULT '1' COMMENT '1启用0禁用',
  `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1本人,2本人及下属,3本部门,4本部门及下属部门,5全部 ',
  `types` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1超级管理员2系统设置管理员3部门与员工管理员4审批流管理员5工作台管理员6客户管理员7项目管理员8公告管理员',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='角色表';

group表的rules字段关联rule表的自增id

 

用户所属组:

CREATE TABLE `5kcrm_admin_access` (
  `user_id` int(11) NOT NULL,
  `group_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf

   user_id                            group_id

通过group的自增id 就是 access表group_id,查到对应的user_id 就是 用户表的id

 

对于部门表structure 有 id, name, pid字段
id关联用户表的 structure_id

 

主要的代码:

application/admin/model/User.php

    /**
     * [getUserByPer 获取权限范围的user_id]
     * @param string $m
     * @param string $c
     * @param string $a
     * @return array|bool
     */
    public function getUserByPer($m = 'index', $c = 'index', $a = 'index'){
        $request = Request::instance();
        $header = $request->header();
        $authKey = $header['authkey'];

        $m = $m ? strtolower($m) : strtolower($request->module());
        $c = $c ? strtolower($c) : strtolower($request->controller());
        $a = $a ? strtolower($a) : strtolower($request->action());

        $cache = cache('Auth_'.$authKey);
        if (!$cache) {
            return false;
        }
        $userInfo = $cache['userInfo'];
        //用户所属用户组类别(数组)
        $groupTypes = $this->getGroupTypeByAction($userInfo['id'], $m, $c, $a);
        //数组去重
        $groupTypes = $groupTypes ? array_unique($groupTypes) : [];
        //用户组类别(1本人,2本人及下属,3本部门,4本部门及下属部门,5全部)
        $adminIds = $this->getAdminId();
        $userIds = [];
        if (in_array($userInfo['id'],$adminIds)) {
            $userIds = getSubUserId(true, 1);
        } else {
            if (!$groupTypes) {
                return [];
            }
            if (in_array(5, $groupTypes)) {
                $userIds = getSubUserId(true, 1);
            } else {
                foreach ($groupTypes as $v) {
                    if ($v == 1) {
                        $userIds = [$userInfo['id']];
                    } elseif ($v == 2) {
                        $userIds = getSubUserId();
                    } elseif ($v == 3) {
                        $userIds = $this->getSubUserByStr($userInfo['structure_id']);
                    } elseif ($v == 4) {
                        $userIds = $this->getSubUserByStr($userInfo['structure_id'], 2);
                    }
                }
            }
        }
        return $userIds ? : [];
    }

获取下属的id:

application/common.php

/**
 * 获取下属userId
 * @author Michael_xu
 * @param $self == true  包含自己
 * @param $type == 0  下属userid
 * @param $type == 1  全部userid
 */
function getSubUserId($self = true, $type = 0)
{   
    $request = Request::instance();
    $header = $request->header();    
    $authKey = $header['authkey'];
    $cache = cache('Auth_'.$authKey);
    if (!$cache) {
        return false;
    }
    $userInfo = $cache['userInfo'];

    $adminTypes = adminGroupTypes($userInfo['id']);  
    if (in_array(1,$adminTypes)) {
        $type = 1;
    }    

    $belowIds = [];
    if (empty($type)) {
        $belowIds = getSubUser($userInfo['id']);
    } else {
        $belowIds = getSubUser(0);
    }   
    if ($self == true) {
        $belowIds[] = $userInfo['id'];
    } else {
        $belowIds = $belowIds ? array_diff($belowIds,array($userInfo['id'])) : [];
    }
    return array_unique($belowIds);
}

/**
 * 获取下属userId
 * @author Michael_xu
 */
function getSubUser($userId)
{
    $sub_user = db('admin_user')
        ->where('parent_id', '=', $userId)
        ->where('status', '<>', 2)
        ->column('id');
    if ($sub_user) {
        foreach ($sub_user as $v) {
            $son_user = getSubUser($v);
            if (!empty($son_user)) {
                $sub_user = array_merge($sub_user, $son_user);
            }
        }
    }
    return $sub_user;
}

 

 

application/bi/common.php

<?php
//权限控制
\think\Hook::add('check_auth','app\\common\\behavior\\AuthenticateBehavior');

application/common/behavior/AuthenticateBehavior.php

<?php
// +---------------------------------------------------------------------+
// | Description: WEB端权限判断                                           |
// +---------------------------------------------------------------------+
namespace app\common\behavior;

use think\Request;

class AuthenticateBehavior
{
	public function run(&$params)
	{
        /*防止跨域*/      
        header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, authKey, sessionId");        
        $request = Request::instance();
        $m = strtolower($request->module());
        $c = strtolower($request->controller());
        $a = strtolower($request->action());        
        //提交方式拦截
        $scan = new \com\Scan();
        $response = $scan->webscan_Check();
		
		$allow = $params['allow']; //登录用户可访问
		$permission = $params['permission']; //无限制
		/*获取头部信息*/ 
        $header = $request->header();
        $authKey = $header['authkey'];
		$cache = cache('Auth_'.$authKey);

        $userInfo = $cache['userInfo'];
    	
    	if (in_array($a, $permission)) {
    		return true;
    	}   

    	if (empty($userInfo)) {
			header('Content-Type:application/json; charset=utf-8');
            exit(json_encode(['code'=>101,'error'=>'请先登录']));
    	}
		if ($userInfo['id'] == 1) {
    		return true;
    	}
    	if (in_array($a, $allow)) {
			return true;
    	}
        //管理员角色
        $adminTypes = adminGroupTypes($userInfo['id']);
        if (in_array(1,$adminTypes)) {
            return true;
        }        
        //操作权限
    	$res_per = checkPerByAction($m, $c, $a); 
    	if (!$res_per) {
			header('Content-Type:application/json; charset=utf-8');
            exit(json_encode(['code'=>102,'error'=>'无权操作']));
    	}
	}
}

在控制器中添加方法  _initialize()

    /**
     * 用于判断权限
     * @permission 无限制
     * @allow 登录用户可访问
     * @other 其他根据系统设置
     **/
    public function _initialize() {
        // 权限控制忽略大小写 必须全部转换为小写
        $action = [
            'permission'=>['read', 'index', 'arealist', 'schoollist', 'save', 'update', 'crypt'],
            'allow'=>['arealist']
        ];
        Hook::listen('check_auth',$action);
        $request = Request::instance();
        $a = strtolower($request->action());
        if (!in_array($a, $action['permission'])) {
            parent::_initialize();
        }
    }

action指的是 控制器的方法

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fareast_mzh

打赏个金币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值