- <span style="font-family:Arial, Helvetica, sans-serif;background-color:rgb(255,255,255);">在這個項目設計之前,老闆要求使用權限設計,我比較了一些設計方式,感覺都不錯,於是綜合了一下,自己寫一種權限管理</span>
在權限這一塊出於安全性考慮,我驗證的比較複雜,或許存在不足,如有意見可以交流
一: 管理員表(如下圖)
- CREATE TABLE `czl_admin` (
- `adid` int(11) NOT NULL AUTO_INCREMENT,
- `adname` varchar(20) NOT NULL,
- `password` varchar(32) NOT NULL,
- `addlogip` varchar(18) NOT NULL DEFAULT '127.0.0.1',
- `adlogtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- `adregtime` int(10) NOT NULL,
- `type` tinyint(1) DEFAULT '0',
- `rid` tinyint(3) NOT NULL DEFAULT '0',
- PRIMARY KEY (`adid`),
- UNIQUE KEY `adname` (`adname`)
- ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
權限表
- CREATE TABLE `czl_power` (
- `powerid` tinyint(3) NOT NULL AUTO_INCREMENT,
- `controller` varchar(15) NOT NULL,
- `action` varchar(15) NOT NULL,
- `powername` varchar(15) NOT NULL,
- PRIMARY KEY (`powerid`)
- ) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
如下表
角色表
- CREATE TABLE `czl_role` (
- `roleid` tinyint(4) NOT NULL AUTO_INCREMENT,
- `powerid` varchar(50) NOT NULL,
- `rolename` varchar(10) NOT NULL,
- PRIMARY KEY (`roleid`)
- ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
字段和建表sql如上,
admin表中rid和角色表關聯
角色表powerid和權限表關聯
角色所屬的權限以字符串的形式存放在表中
我使用的是tp3.2 ,當然權限問題是通用的,和框架沒太大關係
代碼如下
- <?php
- namespace Admin\Controller;
- use Think\Controller;
- /*
- * 張鵬飛
- * 2017.4.1
- * 權限
- *
- */
- class BaseController extends Controller{
- function _initialize(){
- $adname = cookie('adname');
- $adid = cookie('adid');
- if (!isset($adid) && !isset($adname)){
- header('location:'.U('Log/index'));
- die;
- }
- // 登錄用戶進行再次驗證
- $where = array(
- 'adname' => passport_decrypt($adname,C('PASSWORD_KEY')),
- 'adid' => passport_decrypt($adid,C('PASSWORD_KEY')),
- );
- $admin = D('Admin');
- $adminArr = $admin->where($where)->find();
- if(empty($adminArr)){
- // 判斷是否爲合法數據
- header('location:'.U('Home/Index/index'));
- die;
- }
- // 對角色進行管理
- // 得到對應的角色以及權限
- $role = D('role');
- $roleArr = $role->find($adminArr['rid']);
- if(empty($roleArr)){
- // 若沒有對應的權限則爲非法用戶
- header('location:'.U('Home/Index/index'));
- die;
- }
- $power = D('Power');
- $powerid = explode('|', $roleArr['powerid']);
- $where['powerid'] = ':powerid';
- foreach ($powerid as $k => $v) {
- $powerTotalArr[] = $power->field('controller,action')->where($where)->bind(':powerid',$v['powerid'])->find();
- }
- // 做兩層判斷
- // 對路徑進行判斷
- $controller = strtolower(CONTROLLER_NAME);
- $action = strtolower(ACTION_NAME);
- $flag = false;
- foreach ($powerTotalArr as $k => $v) {
- if(strtolower($v['controller']) == $controller && strtolower($v['action']) == $action){
- $flag = true;
- }
- }
- if(!$flag) exit('您沒有權限');
- // 重組控制器和方法
- foreach ($powerTotalArr as $k => $v) {
- if(!in_array($v['controller'],$powerTotalArrStr)) $powerTotalArrStr[] = strtolower($v['controller']);
- $powerTotalArrStr[] = strtolower($v['controller']).'/'.strtolower($v['action']);
- }
- $this->assign('powerTotalArrStr',$powerTotalArrStr);
- }
- }
--------------------------------------------------------------------------------------------
以下爲分析過程
---------------------------------------------------------------------------------------------
登錄之後會存放cookie,這裏我對cookie做最基本的判斷
- if (!isset($adid) && !isset($adname)){
- header('location:'.U('Log/index'));
- die;
- }
這裏是對存放的cookie進行驗證,防止有人僞造cookie
adid和adname來查數據表
- if (!isset($adid) && !isset($adname)){
- header('location:'.U('Log/index'));
- die;
- }
- // 登錄用戶進行再次驗證
- $where = array(
- 'adname' => passport_decrypt($adname,C('PASSWORD_KEY')),
- 'adid' => passport_decrypt($adid,C('PASSWORD_KEY')),
- );
- $admin = D('Admin');
- $adminArr = $admin->where($where)->find();
- if(empty($adminArr)){
- // 判斷是否爲合法數據
- header('location:'.U('Home/Index/index'));
- die;
- }
- passport_decrypt 這是解密函數,在前面的文章中有此介紹 <a href="http://blog.csdn.net/fei003/article/details/66472358" target="_blank">http://blog.csdn.net/fei003/article/details/66472358</a> ,
對權限進行初步驗證,此時訪問鏈接的話,會拒絕並跳轉 ,但是如何在頁面中實現權限呢,就是說沒有權限的菜單不會顯示
- <span style="font-family:Arial, Helvetica, sans-serif;"> </span><span style="font-family:Arial, Helvetica, sans-serif;"> <span> </span>// 對角色進行管理</span>
- // 得到對應的角色以及權限
- $role = D('role');
- $roleArr = $role->find($adminArr['rid']);
- if(empty($roleArr)){
- // 若沒有對應的權限則爲非法用戶
- header('location:'.U('Home/Index/index'));
- die;
對權限進行重組,並傳值到模板中,在這裏如果該用戶沒有此權限,經過判斷後則對菜單進行屏蔽處理
- foreach ($powerTotalArr as $k => $v) {
- if(!in_array($v['controller'],$powerTotalArrStr)) $powerTotalArrStr[] = strtolower($v['controller']);
- $powerTotalArrStr[] = strtolower($v['controller']).'/'.strtolower($v['action']);
- }
- $this->assign('powerTotalArrStr',$powerTotalArrStr);