1、首先说一下什么是RBAC
基于角色的访问控制(Role-Based Access Control),作为传统访问控制(自主访问,强制访问)的有前景的受到广泛的关注,在RBAC中,权限与角色相关联,用户通过角色的成员得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据他的责任和资格来被指派响应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并并赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。
2、测试中我们可以做一个简单的登录,将用户名和id存入到session中,方便以后的使用
3、yii框架中的权限分配
我们在学习PHP的过程中应该对TP框架中的RBAC很熟悉,其实框架之间的内容大多数都是相同的,下面让我们来看一下yii框架中的RBAC。
配置RBAC
在开始定义授权数据和执行存取检查之前,需要先配置应用组件yii/base/Application::authManager。yii提供了两套授权管理器;yii/rbac/phpManager和yii/rbac/DbManager。牵着使用PHP脚本存放授权数据,而后者使用数据库存放授权数据。如果你的应用不要求大量的动态角色和权限管理,你可以考虑使用前者。
下面是两个文件的位置
配置在frontend/backend文件夹,config文件夹下main.php
或者
有关yii2使用RBAC地址:http://www.yiifans.com/forum.php?mod=viewthread&tid=11244
我们此时用自己的方法套用YII2框架实现RBAC
RBAC实现思路:
所需表:3、再用当前的的控制器和方法进行比对 如果没有就权限给出提示
难点:表关系的处理、查询语句、以及节点赋权时 多选框 点击一级其余子级选中、点击子级父级选中
笔者运用的ACE后台模板
效果展示:
节点列表
角色列表
角色节点赋权
用户角色赋权
代码实例:
common控制器
namespace frontend\controllers;
header("content-type:text/html;charset=utf-8");
use Yii;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\ContactForm;
use yii\db\Query;
class CommonController extends Controller{
/**
* @param \yii\base\Action $action
* @return bool
* @throws BadRequestHttpException
*/
public function beforeAction($action){
$session=\Yii::$app->session;
$user_session=$session->get('user');
//判断是否有登录session
if(!isset($user_session)){
echo "alert('请先登录');location.href='index.php?r=login/login'";die;
}
//设置超级管理员
if($user_session=="admin"){
return true;
}
//判断权限
$ctl=Yii::$app->controller->id; //获取当前访问的控制器
$action=Yii::$app->controller->action->id; //获取当前访问的方法
//当访问后台是首页权限是公共的
if($ctl=="admin" && $action=="index"){
return true;
}
$id_session=$session->get('id'); //接到用户登录时存的id
$sql="select rn.node_id,n.controller,n.action from role_node as rn left join node as n on rn.node_id=n.node_id where role_id in(SELECT role_id from user_role where user_id=$id_session) group by rn.node_id";
$rows=Yii::$app->db->createCommand($sql)->queryAll(); //查询出该角色的权限
if($rows){
foreach($rows as $key => $val){
if($val['controller']==$ctl && $val['action']==$action){
return true;
}
}
echo "alert('抱歉,您的权限不够');location.href='index.php?r=admin/index'";
return false;
}else{
echo "alert('抱歉,您的权限不够');location.href='index.php?r=admin/index'";
}
if (!parent::beforeAction($action)) {
return false;
}
return true;
}
}
用户控制器
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use yii\db\Query;
use yii\data\Pagination;
class UsersController extends CommonController{
public $layout = 'admin';
/**显示页面
* @return void
*/
public function actionShow(){
$query = new Query();
//查询出所有的数据
$userList = $query->from('user')->where(['is_delete'=>0])->all();
//统计数据个数
$count = count($userList);
//实例化分页类
$pagination = new Pagination(['totalCount' => $count]);
$pagination->setPageSize(2 );
$data = $query->offset($pagination->offset)->limit($pagination->limit)->all();
return $this->render('show', ['data' => $data, 'pagination' => $pagination,]);
}
/**
* 删除
* @return void
*/
public function actionDel()
{
$db = Yii::$app->db;
$id = Yii::$app->request->get('user_id');
$res = $db->createCommand()->update('user',['is_delete'=>1],['user_id'=>$id])->execute();
if($res)
{
echo "alert('删除成功');location.href='index.php?r=users/show'";
}else{
echo "alert('删除失败');location.href='index.php?r=users/show'";
}
}
/**
*添加
* @return void
*/
public function actionAdd(){
$request = YII::$app->request;
if($request->isPost) {
$user_name = $request->post('user_name');
$user_pwd = $request->post('user_pwd');
$user_time=date("Y-m-d H:i:s",time());
$res=Yii::$app->db->createCommand()->insert('user', ['user_name' => $user_name,'user_pwd'=>$user_pwd,'user_time'=>$user_time])->execute();
if($res){
echo "alert('添加成功');location.href='index.php?r=users/show'";
}else{
echo "alert('添加失败');location.href='index.php?r=users/show'";
}
}else{
return $this->render('add');
}
}
/**
* 修改数据
* @return void
*/
public function actionUpda()
{
$request = YII::$app->request;
if($request->isPost){
$user_name=$request->post('user_name');
$user_pwd=$request->post('user_pwd');
$user_id=$request->post('user_id');
$res=Yii::$app->db->createCommand()->update('user', ['user_name' => $user_name,'user_pwd'=>$user_pwd], "user_id = $user_id")->execute();
if($res){
echo "alert('修改成功');location.href='index.php?r=users/show'";
}else{
echo "alert('修改失败');location.href='index.php?r=users/show'";
}
}
if($request->get('user_id')){
$id=$request->get('user_id');
$data = Yii::$app->db->createCommand("SELECT * FROM user WHERE user_id=$id")->queryOne();
return $this->render('upda', ['userInfo' => $data]);
}
}
/**用户角色赋权
* @return string
* @throws \yii\db\Exception
*/
public function actionAuthority(){
$request = YII::$app->request;
$db = Yii::$app->db;
if($request->isPost){
$request->post();
$role_ids= $request->post('role_id');
$user_id= $request->post('user_id');
//查询派生表中数据
$sql="select * from user_role where user_id=$user_id";
$user_role=Yii::$app->db->createCommand($sql)->queryAll();
if($user_role){
//删除派生表中原有数据
$re=Yii::$app->db->createCommand()->delete('user_role', "user_id = $user_id")->execute();
//判断是否接到值
if($role_ids){
foreach($role_ids as $v){
$res=Yii::$app->db->createCommand()->insert('user_role', ['user_id' => $user_id,'role_id'=>$v])->execute();
}
if($res){
echo "alert('角色赋权成功');location.href='index.php?r=users/show'";die;
}else{
echo "alert('角色赋权失败');location.href='index.php?r=users/show'";die;
}
}else{
echo "alert('清除所有角色');location.href='index.php?r=users/show'";die;
}
}else{
if($role_ids){
foreach($role_ids as $v){
$res=Yii::$app->db->createCommand()->insert('user_role', ['user_id' => $user_id,'role_id'=>$v])->execute();
}
if($res){
echo "alert('角色赋权成功');location.href='index.php?r=users/show'";die;
}else{
echo "alert('角色赋权失败');location.href='index.php?r=users/show'";die;
}
}else{
echo "alert('清除所有角色');location.href='index.php?r=users/show'";die;
}
}
}
if($request->isGet){
//查询角色表
$query = new Query();
//查询出所有的数据
$roleList = $query->from('role')->where(['is_delete'=>0])->all();
$user_id = Yii::$app->request->get('user_id');
//查询用户拥有角色
$sql="select * from user_role where user_id=$user_id";
$user_role=Yii::$app->db->createCommand($sql)->queryAll();
$arr=array();
foreach($user_role as $v){
$arr[]=$v['role_id'];
}
//前台多选框选中字段添加
foreach($roleList as $k=>$val){
if(in_array($val['role_id'],$arr)){
$roleList[$k]['check']="check";
}else{
$roleList[$k]["check"]="false";
}
}
return $this->render('authority',['roleList'=>$roleList,'user_id'=>$user_id,'user_role'=>$user_role]);
}
}
}
角色控制器
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use yii\db\Query;
use yii\data\Pagination;
class RoleController extends CommonController{
public $layout = 'admin';
public function actionShow(){
$query = new Query();
//查询出所有的数据
$userList = $query->from('role')->where(['is_delete'=>0])->all();
//统计数据个数
$count = count($userList);
//实例化分页类
$pagination = new Pagination(['totalCount' => $count]);
$pagination->setPageSize(2 );
$data = $query->offset($pagination->offset)->limit($pagination->limit)->all();
return $this->render('show', ['data' => $data, 'pagination' => $pagination,]);
}
/**
* 删除
* @return void
*/
public function actionDel()
{
$db = Yii::$app->db;
$id = Yii::$app->request->get('role_id');
$res = $db->createCommand()->update('role',['is_delete'=>1],['role_id'=>$id])->execute();
if($res)
{
echo "alert('删除成功');location.href='index.php?r=role/show'";
}else{
echo "alert('删除失败');location.href='index.php?r=role/show'";
}
}
/**
* 修改数据
* @return [type] [description]
*/
public function actionUpda()
{
$request = YII::$app->request;
if($request->isPost){
$role_name=$request->post('role_name');
$role_desc=$request->post('role_desc');
$role_start=$request->post('role_start');
$role_id=$request->post('role_id');
$res=Yii::$app->db->createCommand()->update('role', ['role_name' => $role_name,'role_desc'=>$role_desc,'role_start'=>$role_start], "role_id = $role_id")->execute();
if($res){
echo "alert('修改成功');location.href='index.php?r=role/show'";
}else{
echo "alert('修改失败');location.href='index.php?r=role/show'";
}
}
if($request->get('role_id')){
$id=$request->get('role_id');
$data = Yii::$app->db->createCommand("SELECT * FROM role WHERE role_id=$id")->queryOne();
return $this->render('upda', ['roleInfo' => $data]);
}
}
/**添加角色
* @return string
* @throws \yii\db\Exception
*/
public function actionAdd(){
$request = YII::$app->request;
if($request->isPost){
$role_name=$request->post('role_name');
$role_desc=$request->post('role_desc');
$role_start=$request->post('role_start');
$role_time=date("Y-m-d H:i:s",time());
$res=Yii::$app->db->createCommand()->insert('role', ['role_name' => $role_name,'role_desc'=>$role_desc,'role_start'=>$role_start,'role_time'=>$role_time])->execute();
if($res){
echo "alert('添加成功');location.href='index.php?r=role/show'";
}else{
echo "alert('添加失败');location.href='index.php?r=role/show'";
}
}else{
return $this->render('add');
}
}
/**角色节点赋权
* @return string
* @throws \yii\db\Exception
*/
public function actionAuthority(){
$request = YII::$app->request;
if($request->isPost){
$request->post();
$node_ids= $request->post('node_id');
$role_id= $request->post('role_id');
//查询派生表中数据
$sql="select * from role_node where role_id=$role_id";
$role_node=Yii::$app->db->createCommand($sql)->queryAll();
if($role_node){
//删除派生表中原有数据
$re=Yii::$app->db->createCommand()->delete('role_node', "role_id = $role_id")->execute();
//判断是否接到值
if($node_ids){
foreach($node_ids as $v){
$res=Yii::$app->db->createCommand()->insert('role_node', ['role_id' => $role_id,'node_id'=>$v])->execute();
}
if($res){
echo "alert('节点赋权成功');location.href='index.php?r=role/show'";die;
}else{
echo "alert('节点赋权失败');location.href='index.php?r=role/show'";die;
}
}else{
echo "alert('清除所有节点');location.href='index.php?r=role/show'";die;
}
}else{
if($node_ids){
foreach($node_ids as $v){
$res=Yii::$app->db->createCommand()->insert('role_node', ['role_id' => $role_id,'node_id'=>$v])->execute();
}
if($res){
echo "alert('节点赋权成功');location.href='index.php?r=role/show'";die;
}else{
echo "alert('节点赋权失败');location.href='index.php?r=role/show'";die;
}
}else{
echo "alert('清除所有节点');location.href='index.php?r=role/show'";die;
}
}
}
if($request->isGet){
$id = Yii::$app->request->get('role_id');
//查询出所有节点
$query = new Query();
//查询出所有的数据
$nodeList = $query->from('node')->all();
$nodeLists=$this->sort_a($nodeList);
//查询出派生表中角色所定义的节点id
$role_node= Yii::$app->db->createCommand("SELECT * FROM role_node where role_id=$id")->queryAll();
//循环两个数组将角色对应的节点增加选中字段
$arr=array();
foreach($role_node as $v){
$arr[]=$v['node_id'];
}
foreach($nodeLists as $k=>$val){
if(in_array($val['node_id'],$arr)){
$nodeLists[$k]['check']="check";
}else{
$nodeLists[$k]['check']="false";
}
}
return $this->render('authority',['nodeLists'=>$nodeLists,'role_id'=>$id]);
}
}
/** 递归
* @param 列表数据
* @param int 父类id
* @param int 间隔
* @return array
*/
public function sort_a($res,$sid=0,$level=0){
static $arr=array();
foreach($res as $key=>$val){
if($val['parent_id']==$sid){
$val['level']=str_repeat(" ",$level);
$arr[]=$val;
$this->sort_a($res,$val['node_id'],$level+1);
}
}
return $arr;
}
}
节点控制器
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use yii\db\Query;
use yii\data\Pagination;
class NodeController extends CommonController{
public $layout = 'admin';
public function actionShow(){
$query = new Query();
//查询出所有的数据
$nodeList = $query->from('node')->all();
$nodeLists=$this->sort_a($nodeList);
return $this->render('show', ['data' => $nodeLists]);
}
/** 递归
* @param 列表数据
* @param int 父类id
* @param int 间隔
* @return array
*/
public function sort_a($res,$sid=0,$level=0){
static $arr=array();
foreach($res as $key=>$val){
if($val['parent_id']==$sid){
$val['level']=str_repeat(" ",$level);
$arr[]=$val;
$this->sort_a($res,$val['node_id'],$level+1);
}
}
return $arr;
}
/**
* 删除
* @return void
*/
public function actionDel()
{
$db = Yii::$app->db;
$id = Yii::$app->request->get('node_id');
$sql="select * from node where parent_id = $id";
$data = Yii::$app->db->createCommand("$sql")->queryAll();
if($data){
echo "alert('该目录下有子类不能删除');location.href='?r=node/show';";die;
}
$res=Yii::$app->db->createCommand()->delete('node', "node_id = $id")->execute();
if($res)
{
echo "alert('删除成功');location.href='index.php?r=node/show'";
}else{
echo "alert('删除失败');location.href='index.php?r=node/show'";
}
}
/**
* 修改数据
* @return void
*/
public function actionUpda()
{
$request = YII::$app->request;
if($request->isPost){
$node_title=$request->post('node_title');
$controller=$request->post('controller');
$action=$request->post('action');
$parent_id=$request->post('parent_id');
$node_id=$request->post('node_id');
$res=Yii::$app->db->createCommand()->update('node', ['node_title' => $node_title,'controller'=>$controller,'action'=>$action,'parent_id'=>$parent_id], "node_id = $node_id")->execute();
if($res){
echo "alert('修改成功');location.href='index.php?r=node/show'";
}else{
echo "alert('修改失败');location.href='index.php?r=node/show'";
}
}
if($request->get('node_id')){
$query = new Query();
//查询出所有的数据
$nodeList = $query->from('node')->all();
$nodeLists=$this->sort_a($nodeList);
$id=$request->get('node_id');
$data = Yii::$app->db->createCommand("SELECT * FROM node WHERE node_id=$id")->queryOne();
return $this->render('upda', ['nodeInfo' => $data,'nodelist'=>$nodeLists]);
}
}
/**节点添加
* @return string
* @throws \yii\db\Exception
*/
public function actionAdd(){
$query = new Query();
//查询出所有的数据
$nodeList = $query->from('node')->all();
// print_R($nodeList);exit;
$nodeLists=$this->sort_a($nodeList);
$request = YII::$app->request;
if($request->isPost){
// print_r( $request->post());exit;
$node_title=$request->post('node_title');
$controller=$request->post('controller');
$action=$request->post('action');
$parent_id=$request->post('parent_id');
$res=Yii::$app->db->createCommand()->insert('node', ['node_title' => $node_title,'controller'=>$controller,'action'=>$action,'parent_id'=>$parent_id])->execute();
if($res){
echo "alert('添加成功');location.href='index.php?r=node/show'";
}else{
echo "alert('添加失败');location.href='index.php?r=node/show'";
}
}else{
return $this->render('add',['nodelist'=>$nodeLists]);
}
}
}
显示页面就不一一展示了,笔者只将用户赋角和角色赋节点两个页面展示
1、用户赋角
class="main-content">
class="breadcrumbs" id="breadcrumbs">
class="breadcrumb">
-
class="icon-home home-icon">
href="#">角色授权
- class="active">控制台
class="nav-search" id="nav-search">
class="page-content">
class="page-header">
权限管理功能
class="icon-double-angle-right">
角色授权
2、角色赋节点
class="main-content">class="breadcrumbs" id="breadcrumbs">class="breadcrumb">
- class="icon-home home-icon"> href="#">节点授权
- class="active">控制台
class="nav-search" id="nav-search">class="page-content">class="page-header">权限管理功能 class="icon-double-angle-right"> 节点授权