author:咔咔


 

在写rbac前我们先创建一个权限白名单,这个白名单就是不需要校验的模块

【TP5.1】Rbac设计_方法名

下来创建一个工具类Rbac

【TP5.1】Rbac设计_方法名_02

源码:

在验证白名单这块,我之前使用了错误的校验的方法。

在第一次的时候,认为只需要验证module,controller,action都不为空,并且都为true时是需要校验的,经过多次测试后,发现这样是不行的,因为当module不存在的时候,验证module是true没错,但是在验证controller时就会报错。因为没有这个module,所以什么都不返回,这里的判断还是一个与的运算符,所以会一直走false

 

所以就出现了最后的那段代码:

        /**

         * 当module存在白名单时返回false,进行action的验证

         * 当module不存在的时候返回true,进入iif判断

         * 在继续验证controller,当controller不存在白名单时返回true,进入if判断返回false

         * 当验证controller存在时返回false,进行action的验证

         * 当module和controller都存在时返回的都是false,就进行action的验证

         */

 

<?php

namespace data\util;

use Request,SC,Config,Log;

class Rbac
{
// 模块名
private $module;
// 控制器名
private $controller;
// 方法名
private $action;
// 需要检验的模块
private $authModule = [
'admin'
];

/**
* Rbac constructor.
* 在Rbac初始化的时候,获取用户请求的url 从而校验权限
* 模块名 module
* 控制器名 controller
* 方法名 action
*/
public function __construct()
{
$this->module = strtolower(request()->module());
$this->controller = strtolower(request()->controller());
$this->action = strtolower(request()->action());
}

/**
* 做权限校验,校验用户访问的模块是否在自定义的模块里
*/
public function check()
{
// 需要检验用户是否登录成功,在登录成功之后在做校验
if(!SC::getLogin()){
return false;
}
/**
* 判断用户访问的模块是否在需要校验的模块
*/
if(in_array($this->module,$this->authModule)){
/**
* 如果用户不是系统后台用户那就需要权限验证
*/
if(!SC::getIsSystem()){
return false;
}
/**
* 用户为非后台用户需要做全面校验
* 1.首先通过url判断用户是否需要权限
* 2.如果需要权限,判断用户是否为权限用户
* 3.进行权限校验
*/
}
return true;
}

/**
* 验证白名单用户
*/
public function checkWhite()
{
// 获取白名单模块
$white = Config::get('white.');
/**
* empty 检查一个变量是否为空 为空时返回true
* isset 检测变量是否设置 不存在返回false
* 当白名单都没有用户输入的url时需要进行校验
*/
/*if(empty($white[$this->module]) || empty($white[$this->module][$this->controller])){
return false;
}

if(empty($white[$this->module][$this->controller][$this->action])){
return false;//需要校验
}else{
return true;//不需要检验
}*/
// Log::write(!empty($white[$this->module]).'刘牛牛啊');

// Log::write($white[$this->module][$this->controller].'刘牛牛啊');

// Log::write(empty($white[$this->module][$this->controller][$this->action]).'刘牛牛啊');

// if(!empty($white[$this->module]) && !empty($white[$this->module][$this->controller]) && !empty($white[$this->module][$this->controller][$this->action])){
// Log::write('需要校验');
// return false;//需要校验
// }else{
// Log::write('不需要校验刘牛');
// return true;//不需要检验
// }

/**
* 当module存在白名单时返回false,进行action的验证
* 当module不存在的时候返回true,进入iif判断
* 在继续验证controller,当controller不存在白名单时返回true,进入if判断返回false
* 当验证controller存在时返回false,进行action的验证
* 当module和controller都存在时返回的都是false,就进行action的验证
*/
if (empty($white[$this->module]) || empty($white[$this->module][$this->controller])) {
// 先判断访问地址是否白名单中
return false; //需要权限校验
}
Log::write($white[$this->module][$this->controller]);
if (in_array($this->action, $white[$this->module][$this->controller])) { //判断方法是否在白名单列表中
Log::write('你好,你不需要校验');
return true;
} else {
Log::write('你好,需要校验');
return false; //需要权限校验
}
}

}

 在创建一个Rbac的门面类

【TP5.1】Rbac设计_初始化_03

 对门门面类进行代理和别名设置

【TP5.1】Rbac设计_白名单_04

创建中间件

【TP5.1】Rbac设计_中间件_05

源码:

<?php

namespace app\http;

use SC,OnlyLogin,Rbac;

class AuthMiddleware
{
public function handle($request, \Closure $next)
{
/**
* 使用中间件进行白名单判断,判断用户是否权限需要校验
* Rbac::checkWhite()返回的是boolean
* true不需要校验直接返回请求
*/
if(Rbac::checkWhite()){
return $next($request);
}

/**
* 检测用户是否是唯一登录
*/
if (OnlyLogin::onlyCheck()) {
/**
* 检测用户是否有权限
*/
if(Rbac::check()){
return $next($request);
}else{
return redirect($request->module().'/login/login');
}
}else{
return redirect('你被T了');
}
}
}

 过俩天在总结思路.....