【TP5.1】Rbac设计
源码:
在验证白名单这块,我之前使用了错误的校验的方法。
在第一次的时候,认为只需要验证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; //需要权限校验 } } }
源码:
<?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了'); } } }