rbac(php)

来源:互联网 发布:格式转换软件 编辑:程序博客网 时间:2024/06/06 05:35
首先,类似于rbac一样,我们需要在数据库建立3张表,这里会比rbac少一张表,我是觉得没有必要弄得那么复杂。那么第一张是用户表user,用来存管理员且分配用户组,第二张表就是组权限表access,用来存用户组及权限表,第三张是动作方法表method,用来存控制器和方法及一些控制器和方法的说明等,建好这三张表,数据库这边的准备工作就基本完成了。

第二步,写出自己需要的html页面来让用户输入这三张表需要填充的类容。写个控制器来接收存库就好了,由于这个地方太基础,我就不啰嗦了,实在不行可以给我留言。

第三部,编写权限管理类,我自己给命了个名字AUTHHW.class.php,那么里面的类容我就不详细说了,反正都是要上代码的,我由于不是大神,所以写的代码应该你们都是能看懂的,所以我就不逼逼了,这个类的算法如下:
AUTHHW.class.php
  1. <?php 
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | 纯属业余研究,希望大神指点
  8. // +----------------------------------------------------------------------
  9. // | Author: yxw admin@yxw21.com  杨小二 617190787@qq.com
  10. // +----------------------------------------------------------------------
  11. namespace Org\Util;
  12. use Think\Db;
  13. /**
  14.  +------------------------------------------------------------------------------
  15.  * 基于角色的数据库方式验证类
  16.  +------------------------------------------------------------------------------
  17.  */

  18. /*
  19. -- --------------------------------------------------------
  20. 权限表建表语句
  21. CREATE TABLE IF NOT EXISTS `access` (
  22.   `id` int(1) NOT NULL AUTO_INCREMENT,
  23.   `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  24.   `tip` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  25.   `access` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
  26.   PRIMARY KEY (`id`)
  27. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;

  28. -- --------------------------------------------------------
  29. //动作方法建表语句
  30. CREATE TABLE IF NOT EXISTS `mothed` (
  31.   `id` int(1) NOT NULL AUTO_INCREMENT,
  32.   `controller` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  33.   `c_tip` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  34.   `method` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  35.   `mtip` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  36.   PRIMARY KEY (`id`)
  37. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;

  38. -- --------------------------------------------------------
  39. 用户建表语句
  40. CREATE TABLE IF NOT EXISTS `user` (
  41.   `id` int(1) NOT NULL AUTO_INCREMENT,
  42.   `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  43.   `pwd` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  44.   `access_id` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  45.   `luck` int(1) NOT NULL DEFAULT '1',
  46.   PRIMARY KEY (`id`)
  47. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

  48. */
  49. class ClassName extends AnotherClass
  50. {
  51.     
  52.     function __construct(argument)
  53.     {
  54.         # code...
  55.     }
  56. }
  57. class AUTHHW {
  58.     static function check_access($c_msg){
  59.         if (!in_array($_SESSION['uname'], explode(";", C("SUPERADMIN")))) {    
  60.         $NOTVERIFY=explode(";",C("NOTVERIFY"));
  61.         $access_id=M('user')->where($map['id']=$_SESSION['uid'])->field('access_id')->find();
  62.         $msg['id']=$access_id['access_id'];
  63.         $access=M('access')->where($map)->field('access')->find();
  64.         $htmlContent=<<<EOF
  65.                 <style>
  66.                 *{margin:0;padding:0;list-style-type:none}
  67.                 div{position: relative;left: 36%;top:35%;width:450px;height:150px;border:1px solid rgb(220,220,220);border-radius:5px;background:rgb(245,250,254);}
  68.                 div p{display:block;width:100%;height:35px;border-radius:5px 5px 0 0;font-family: Microsoft YaHei;font-size:18px;line-height:40px;text-indent:30px;font-weight:bold;color:rgb(99,150,70)}
  69.                 div i{display:block;width:100%;height:1px;border-bottom:1px dashed;opacity:0.2}
  70.                 ul{width:86%;height:60%;margin:10px auto;}
  71.                 h2{font-size:16px;margin-bottom:10px;margin-top:15px;color:rgb(69,116,127);font-family: Microsoft YaHei;}
  72.                 span{font-size:14px;color:rgb(69,116,127);font-family: Microsoft YaHei;}
  73.                 label{display:block;width:70px;font-size:12px;cursor: pointer;margin-top:20px;text-decoration: underline;font-family: Microsoft YaHei;color:grey}
  74.                 img{width:70px;height:70px;position: absolute;right:70px;top:50px;}
  75.                 </style>
  76.                 <body></body>
  77.                 <script>
  78.                 var div= document.createElement("div");
  79.                 div.innerHTML='<p>访问受限</p><i></i><ul><li><h2>您没有访问权限</h2></li><li><span>抱歉,该功能未对当前账号开放!</span></li><li><label onclick="back()">返回》》》</label></li></ul><img src="http://static.tieba.baidu.com/tb/editor/images/client/image_emoticon25.png">';
  80.                 document.body.appendChild(div);
  81.                 function back(){window.location.href="http://localhost/vedioweb/index.php/Admin/Index/index";}
  82.                 </script>
  83. EOF;
  84.         if ($access['access']) {
  85.             $arr=explode(';', $access['access']);
  86.             $flog=false;
  87.             foreach ($arr as $value) {
  88.                 $map['id']=$value;
  89.                 $res=M('mothed')->where($map)->find();
  90.                 if ($c_msg==$res['controller']."/".$res['method']||in_array($c_msg, $NOTVERIFY)){
  91.                     $flog=true;
  92.                     break;
  93.                 }
  94.             }
  95.             if ($flog) {
  96.                 return($flog);
  97.             }else{
  98.                 die($htmlContent);
  99.             }
  100.         }else{
  101.             die($htmlContent);
  102.         }
  103.     }else{
  104.         return true;
  105.     }    
  106.     }

  107.     //重组数组
  108.     function reconarr($res){
  109.         $reconarr=array();
  110.         foreach ($res as $key=>$value) {
  111.             if(inarray($value["controller"], $reconarr,true)===null)$reconarr[]=array("controller"=>$value["controller"],"c_tip"=>$value["c_tip"]);
  112.             $keys=inarray($value["controller"], $reconarr,true);
  113.             if($keys!==null && inarray($value["method"], $reconarr,true)==null)$reconarr[$keys]["child"][]=array("method"=>$value["method"],"m_tip"=>$value["mtip"]);
  114.         }
  115.         return $reconarr;
  116.     }
  117.     function inarray($str,$arr,$flag=false,$keys){
  118.         if(!$flag)return in_array($str, $arr);
  119.         foreach ($arr as $key=>$value){
  120.             if(is_array($value))$res=inarray($str,$value,true,$key);
  121.             if($res!==null)break;
  122.             if($value==$str)return $keys;
  123.         }
  124.         return $res;
  125.     }
  126. }
  127.  ?>
复制代码
逻辑简单,代码量也很少,到这儿我们离成功就很近了,写好了这个类,你把它封装好放到org/Util文件下就可以了。

第四步,编写一个CommonController控制器,在里面写一个方法,实时验证权限,记得把权限类导入进来,也直接上代码吧:
  1. <?php
  2. namespace Admin\Controller;
  3. use Think\Controller;
  4. use Org\Util\AUTHHW;
  5. header("content-type:text/html;charset=utf-8");
  6. class CommonController extends Controller {
  7.         public function _initialize(){
  8.             import('ORG.Util.AUTHHW');
  9.             if(!$_SESSION['uid']){
  10.                 $htmlContent=<<<EOF
  11.                 <style>
  12.                 *{margin:0;padding:0;list-style-type:none}
  13.                 div{position: relative;left: 36%;top:35%;width:450px;height:150px;border:1px solid rgb(220,220,220);border-radius:5px;background:rgb(245,250,254);}
  14.                 div p{display:block;width:100%;height:35px;border-radius:5px 5px 0 0;font-family: Microsoft YaHei;font-size:18px;line-height:40px;text-indent:30px;font-weight:bold;color:rgb(99,150,70)}
  15.                 div i{display:block;width:100%;height:1px;border-bottom:1px dashed;opacity:0.2}
  16.                 ul{width:86%;height:60%;margin:10px auto;}
  17.                 h2{font-size:16px;margin-bottom:10px;margin-top:15px;color:rgb(69,116,127);font-family: Microsoft YaHei;}
  18.                 span{font-size:14px;color:rgb(69,116,127);font-family: Microsoft YaHei;}
  19.                 label{display:block;width:140px;font-size:12px;cursor: pointer;margin-top:20px;text-decoration: underline;font-family: Microsoft YaHei;color:grey}
  20.                 img{width:70px;height:70px;position: absolute;right:70px;top:50px;}
  21.                 </style>
  22.                 <body></body>
  23.                 <script>
  24.                 var div= document.createElement("div");
  25.                 div.innerHTML='<p>访问受限</p><i></i><ul><li><h2>您当前未登陆</h2></li><li><span>抱歉,后台访问需登录后才能继续!</span></li><li><label onclick="back()">前往登陆》》》</label></li></ul><img src="http://static.tieba.baidu.com/tb/editor/images/client/image_emoticon25.png">';
  26.                 document.body.appendChild(div);
  27.                 function back(){window.location.href="http://localhost/vedioweb/index.php/Admin/Login/login";}
  28.                 </script>
  29. EOF;
  30.                 die($htmlContent);}
  31.             AUTHHW::check_access(CONTROLLER_NAME."/".ACTION_NAME);
  32.             
  33.         }
  34. }
复制代码
EOF之间包着的是提示语句,可以根据自己的需求自己改,我不做前端,所以写的很粗糙,这个就让你们自由发挥了。

好了,到这里我们就差最后一步了,到配置文件里面去配置超级管理员和不需要验证的动作方法吧,rbac的配置有很多,而且好像超级管理员只能设置一个,我这个配置的话就2个,不多,但是超级管理员的个数是可以根据你自己的需求任意设置的,但是需要你谨慎设置了,直接给你们上代码吧:
<?php
return array(
//'配置项'=>'配置值'
"SUPERADMIN"=>"yhw;tx",//配置超级管理员,多个账号用“;”隔开;注意,超级管理员为系统最高级别的管理者,不受程序管理,请谨慎配置
"NOTVERIFY"=>"Index/index;Index/dd;Index/logout"//配置不需要验证的方法:控制器/方法,多个方法用“;”隔开
);

好了,现在你把需要验证的控制器里面都继承Common这个控制器就可以用啦
类似这样:class IndexController extends CommonController

好了小伙伴们,快去试试吧。我第一次发这种教程帖子,有什么说的不对的地方请大家多多包涵,我不是特别专业的程序员,有些想法不正确的,希望在座的大神多多提点,程序有什么缺陷也请各位大神批评指导!
原创粉丝点击