Thinkphp Rbac应用篇二

最近因为很多事情都没有做完一直没好意思更新,今天趁着天亮前的空档索性更新一下好了,内容很基础,就是RBAC的实际应用,如果不熟悉的可以看一下上篇。Rbac不完全深入详解

我们在前期的时候知道了rbac的认证流程,其实下面要写代码的话也是依照这个认证流程来的,下面继续来看,翻看Controller.class代码的时候发现这么一行

    public function __construct() {
        Hook::listen('action_begin',$this->config);
        //实例化视图类
        $this->view     = Think::instance('Think\View');
        //控制器初始化
        if(method_exists($this,'_initialize'))
            $this->_initialize();
    }

我们看到, 它在初始化控制器的时候有一句判断, 检测对象自身是否包含初始化方法, 如果包含就就使用当前实例化对象进行读取。这样的话,我们就可以重写该方法,然后让每一个控制器都去继承它,这样再去被继承的控制器里编写验证代码,就会被自动加载。前面知道了, rbac验证首先应该判断是否需要认证, 判断前要先检测是否开启认证,如果未开启认证就进入else。 其实这个各凭喜好,你要愿意开启认证进入else也行,前面我们已经在config里配置了所需要的数组, 这里只需要使用C读取配置信息就可以了。

首先是第一层判断

什么情况下是需要认证的场景?

USER_AUTH_ON = True;

NOT_REQUIRE_MODULE 中不存在指定的模块信息

所以, 这里的第一层判断就可以这么写

       if(C('USER_AUTH_ON') && !in_array(MODULE_NAME,explode(',',C('NOT_AUTH_MODULE'))))

首先读取认证开关选项信息, 如果为真就代表认证已经开启, 又因为加了逻辑与,所以两边条件都得满足, 解释全就是,如果读取到了USER_AUTH_ON为真并且在NOT_AUTH_MODULE数组中没有检测到指定的模块名, 就代表当前需要认证。确定需要认证的时候, 因为我们要使用RBAC类中的方法进行权限检测, 所以要导入它

  import('Org.Util.Rbac');

我们知道, 认证相对意义上包括认证通过和认证不通过,所以导入后就要进行权限是否通过判断

 //权限认证的过滤器方法
    static public function AccessDecision($appName=MODULE_NAME) {
        //检查是否需要认证
        if(self::checkAccess()) {
            //存在认证识别号,则进行进一步的访问决策
            $accessGuid   =   md5($appName.CONTROLLER_NAME.ACTION_NAME);
            if(empty($_SESSION[C('ADMIN_AUTH_KEY')])) {
                if(C('USER_AUTH_TYPE')==2) {
                    //加强验证和即时验证模式 更加安全 后台权限修改可以即时生效
                    //通过数据库进行访问检查
                    $accessList = self::getAccessList($_SESSION[C('USER_AUTH_KEY')]);
                }else {
                    // 如果是管理员或者当前操作已经认证过,无需再次认证
                    if( $_SESSION[$accessGuid]) {
                        return true;
                    }
                    //登录验证模式,比较登录后保存的权限访问列表
                    $accessList = $_SESSION['_ACCESS_LIST'];
                }
                //判断是否为组件化模式,如果是,验证其全模块名
                if(!isset($accessList[strtoupper($appName)][strtoupper(CONTROLLER_NAME)][strtoupper(ACTION_NAME)])) {
                    $_SESSION[$accessGuid]  =   false;
                    return false;
                }
                else {
                    $_SESSION[$accessGuid]  =   true;
                }
            }else{
                //管理员无需认证
                return true;
            }
        }
        return true;
    }

我们查看源码得知, rbac的验证是由AccessDecision使用自身静态方法来进行验证的, 这里会经过几个检测, 那么我们取反, 就代表验证不通过/获取验证所需要的信息不成功。

if(!Rbac::AccessDecision())

当验证不成功的时候, 我们就需要检测这个时候访问对方是否已经登陆, 这里就可以检测session中是否存在已定义的标记, 如果登陆后该标记是会存在的

if(!$_SESSION[C('USER_AUTH_KEY')])

如果没检测到标记, 就代表未登陆, 这个时候可以redirect到public/login。 相反的, 如果检测到了, 就代表已登陆, 已登陆的显示对应的模块信息。这个时候还需要一个判断, 检测是否开启游客授权访问, 如果开启了, 就继续读取游客id是否为预定义数值, 如果是就代表是正常游客, 如果不是就再提示一次登陆页面或者其他提示页面。

连贯一起就是

首先检测是否开启认证和当前模块是否不需要认证, 因为我们要排除直接访问的情况, 所以要这么写, 如果开启了认证并且不需要认证的数组为空, 就代表当前访问需要认证, 这个时候进入认证流程, 导入RBAC模块, 导入后, 验证是否成功, 如果在session中没有发现指定的标记就代表未登陆, 这个时候可以跳回验证页, 相反如果存在, 就代表已登陆, 这个时候可以继续判断, 是否开启了游客授权访问, 如果未开启, 就提示无权限, 如果已开启, 检测标记是否和预定义游客标记相符合, 如果符合, 游客访问成功, 如果不符合, 说明非法访问, 抛出页面。

此条目发表在php分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。

Thinkphp Rbac应用篇二》有 2 条评论

评论功能已关闭。