TP权限建立前两步看这里
1、http://www.fungj.com/information/rbac-thinkphp323-foundation-to-establish-database-permissions.html
2、http://www.fungj.com/information/rbac-thinkphp323-according-to-permissions-to-operate-the-display.html
在TP建立好权限后,有个漏洞,就是如果有原来的开发人员知道相关的控制器和写法,就能跳过前面的权限控制,直接操作。
例如,我的品字形框架,左边都是相关权限操作,而相关的操作方法都是由相关的控制器操作,所以一旦有人知道我的控制器相关位置修改url地址进行访问,那么权限操作就歇菜了。
解决思路:
每次用户访问的控制器和方法都需要和对应的角色里边的ac信息进行比较
ac信息里边存在这个控制器和方法就允许访问,否则禁止访问
首先,我前面做了个组建的目录Component,在这个目录下面在建一个AdminController.class.php文件,用于权限控制。
注意命名空间和使用的命名空间。
namespace Component;
use Think\Controller;
因为我组件这个目录是在根目录下,如果还有目录的话namespace前面也需要加上目录路径。
类依旧继承 Controller 就好。
全部代码为:
<?php
//普通控制器的父类
namespace Component;
use Think\Controller;
class AdminController extends Controller {
//构造方法
function __construct() {
//先执行父类的构造方法,否则系统要报错
//因为原先的构造方法默认是被执行的
parent::__construct();
//CONTROLLER_NAME ---Goods
//ACTION_NAME ----showlist
//当前请求操作
$now_ac = CONTROLLER_NAME . "-" . ACTION_NAME;
//过滤控制器和方法,避免用户非法请求
//通过角色获得用户可以访问的控制器和方法信息
$sql = "select role_auth_ac from sw_manager a join sw_role b on a.mg_role_id=b.role_id where a.mg_id=" . $_SESSION['userid'];
$auth_ac = M()->query($sql);
$auth_ac = $auth_ac[0]['role_auth_ac'];
//判断$now_ac是否在$auth_ac字符串里边有出现过
//strpos函数如果返回false是没有出现,返回0 1 2 3表示有出现
//管理员不限制
//默认以下权限没有限制
//Index/left Index/right Index/head Index/index Manager/login
$allow_ac = array('Index-left', 'Index-right', 'Index-head', 'Index-index', 'Manager-login');
if (!in_array($now_ac, $allow_ac) && $_SESSION['userid'] != 1 && strpos($auth_ac, $now_ac) === false) {
$this->error('没有权限访问', U("Index/right"));
}
}
}
?>
然后在相应的控制器中,把原来默认继承的Controller改为继承AdminController就可以了。
但我想说的是,如果真有和自己一起开发的人跳出去搞你的话,也真心是交友不慎了。
但既然是学习嘛,也记录一下,另外我也有个自己的办法,当然这个只是验证是否为管理人员登录,不登录其他页面也是访问不了的方法。
//后台首页
public function Index() {
//获取SESSION里面的数据
$username = session('username');
$userid = session('userid');
//检查SESSION里面的用户是否存在
$dbuser = M('manager');
$dbinfo = $dbuser->
where("mg_name='$username'")->select();
if ($dbinfo != null) {
//判断是否登录
$this->display();
} else {
$this->error('您还没有登录,请先登录!', U('Manager/login'));
return flase;
}
}
做好首页后,在其他管理页面的方法里把这个方法先实例化一下即可。
$this->Index(); //判断登录
这样子做个从SESSION里面得到的用户去MYSQL里去对比,如果没有的话,就算没登录,其他页面也一样登录不了。
4 条评论
嗯哼?
1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 [ SQL语句 ] : select role_auth_ac from sw_manager as a join sw_role as b on a.mg_role_id=b.role_id where a.mg_id=
MYSQL是什么版本? 另外是TP的数据库表前缀有了么?