Maison développement back-end tutoriel php 浅谈PHP第七弹----基于角色的访问控制RBAC_PHP教程

浅谈PHP第七弹----基于角色的访问控制RBAC_PHP教程

Jul 13, 2016 pm 05:50 PM
http php rbac basé sur 控制 de 角色 访问

上文http://www.BkJia.com/kf/201205/129972.html给大家讲解了使用循环输出九九乘法表,逻辑上还是相对简单一些,重在给大家提供一种看程序,解析代码的方法和思路,有什么意见或者建议可以跟帖批斗....

好了,不多说了,本文来给大家介绍一下“基于角色的访问控制 ”,

说到权限,大家就很头疼,怎么样能灵活把控好一个用户的权限,

有些同学会在用户表中加字段或者是在角色表中加相应的权限字段,

这样会有一个问题,做起权限来会感觉特别的蹩脚,而且很不灵活,每增加一种权限就要在数据库中增加一个字段,很不利于项目的迭代开发

那么我们就需要一种非常灵活的设计模式RBAC,即基于角色的访问控制;

我来给大家说下这种设计思想:

首先,我们的需求是判断某一个用户对当前操作的控制器或控制器的方法是否有权限访问,

如果多个用户同时拥有同样的权限,那我们就需要给这些用户指定同一个用户角色,然后只需要通过角色来对操作的访问进行权限控制,

那我们表结构需要这样来设计,这个很重要,如下:

第一张数据表(用户表):
 

字段名称 字段说明
id 用户ID(主键自增)
username 用户名
password 用户密码
 

第二张数据表(角色表):
 

字段名称 字段说明
id 用户角色ID(主键自增)
name 用户角色名称
   
 
   

第三张数据表(节点表):
 

字段名称 字段说明
id 操作节点ID(主键自增)
name 操作节点的名称
zh_name 节点的中文说明
 

我们使用第三范式来设计关联表,这样做的好处是,避免数据冗余,并且对于一对多,多对一的关系都可以清晰的记录,条理清晰

第四张数据表(节点对应角色表):
 

字段名称 字段说明
role_id 用户角色ID(外键,关联角色表中的主键ID)
note_id 操作节点ID(外键,关联节点表中的主键ID)
   
 

第五张数据表(用户对应角色表):
 

字段名称 字段说明
role_id 用户角色ID(外键,关联角色表中的主键ID)
user_id 用户ID(外键,关联用户表中的主键ID)
   
 

通过这五张表就可以对权限进行访问控制,它的具体操作步骤如下:

用户输入用户名密码登录,
通过用户表判断,如果输入的用户名密码不合法,跳回重新登录
如果合法,在用户表中返回用户的ID号,
通过此用户ID号,到用户与角色的关联表中查询出用户的角色ID号,
拿到角色ID号,通过此ID号到角色与节点的关联表中查询出此角色拥有的节点访问权限,
将此权限节点全部存入SESSION中,当用户访问某一个模块的时候,

例如:http://www.lampbroher.net/index.php/stu/index

我们用session中的权限与$_GET['m']与$_GET['a']去对比,

如果$_GET['m']或者$_GET['a']在SESSION中不存在,说明该用户没有此权限,作出处理即可。

参考代码:

RBAC类文件:
/*+---------------------------------------------------------------------------------------+
| RBAC权限控制类

class Rbac{
private $node_tablename; //定义私有属性节点表名称
private $group_auth_tablename; //定义私有属性组权限表名称
private $group_tablename; //定义私有属性用户组表名称
private $group_user_tablename; //定义私有属性用户归属组表名称
private $user_tablename; //定义私有属性用户表名称
/*
构造方法
@param1 string 节点表名称
@param2 string 用户权限表名称
@param3 string 用户组表名称
@param4 string 用户归属组表名称
@param5 string 用户表名称
*/
public function __construct($node_tablename='node',$group_auth_tablename='group_auth',$group_tablename='group',$group_user_tablename='group_member',$user_tablename='member'){
$this->node_tablename = $node_tablename; //获取节点表名称
$this->group_auth_tablename = $group_auth_tablename; //获取用户权限表名称
$this->group_tablename = $group_tablename; //获取用户组表名称
$this->group_user_tablename = $group_user_tablename; //获取用户归属组表名称
$this->user_tablename = $user_tablename; //获取用户表名称
}
/*
设置节点方法
@param1 string 节点名称
@param2 string 节点父ID
@param2 string 节点中文说明
@return int 插入节点记录成功以后的ID
*/
public function set_node($name,$pid,$zh_name=''){
if(!empty($name) && !empty($pid)){
$node = D($this->node_tablename)->insert(array("name"=>$name,"pid"=>$pid,"zh_name"=>$zh_name));
}
return $node;
}
/*
设置权限方法
@param1 int 组ID
@param2 int 节点ID
@return int 插入权限记录成功以后的ID
*/
public function set_auth($gid,$nid){
if(!empty($gid) && !empty($nid)){
$auth = D($this->group_auth_tablename)->insert(array("gid"=>$gid,"nid"=>$nid));
}
return $auth;
}
/*
获取节点方法
@param1 int 节点ID
@return array 获取到节点表的相关信息
*/
public function get_node($id){
if(!empty($id)){
$data = D($this->node_tablename)->field("id,name,pid")->where(array('id'=>$id))->find();
return $data;
}else{
return false;
}
}
/*
获取组权限方法
@param1 int 用户组ID
@return array 获取到组权限表的相关信息
*/
public function get_auth($gid){
if(!empty($gid)){
$data = D($this->group_auth_tablename)->field("nid")->where(array('gid'=>$gid))->select();
return $data;
}else{
return false;
}
}
/*
获取用户组方法
@param1 int 用户ID
@return array 获取该用户所对应的用户组id
*/
public function get_group($uid){
if(!empty($uid)){
$data = D($this->group_user_tablename)->field("gid")->where(array('uid'=>$uid))->select();
return $data;
}else{
return false;
}
}
/*
获取节点的子节点方法
@param1 int 节点ID
@return array 获取该节点所对应的全部子节点
*/
public function get_cnode($nid){
if(!empty($nid)){
$cnode = D($this->node_tablename)->field("name")->where(array('pid'=>$nid))->select();
return $cnode;
}else{
return false;
}
}
/*
获取权限方法
@param1 int 用户ID
@return array 得到权限列表
*/
public function get_access($uid){
if(!empty($uid)){
//调用获取组信息方法
$group = $this->get_group($uid);
//遍历组信息
foreach($group as $v){
//将组ID传入获取权限的方法
$auth = $this->get_auth($v['gid']); //获取该组的权限
}
//遍历该组的权限数组
foreach($auth as $val){
//将节点的ID传入获取节点信息方法
$node[] = $this->get_node($val['nid']); //获取节点的相关信息
}
//遍历节点数组,并拼装
foreach($node as $nval){
if($nval['pid']==0){
$fnode[] = $nval; //将控制器压入fnode数组
//$cnode = $this->get_cnode($nval['id']);
}else{
$cnode[] = $nval; //将控制器的方法压入cnode数组
}
}
//将控制器数组和控制器数组拼装成一个数组
foreach($fnode as $fval){
foreach($cnode as $cval){
if($cval['pid'] == $fval['id']){
$access[$fval['name']][] = $cval['name'];
}
}
}
//返回权限列表数组
return $access;
}else{
return false;
}
}
/*
检测权限方法
@param1 int 用户ID
@return boolean 权限禁止与否
*/
public function check($uid){
if(!empty($uid)){
//将权限存入到$_SESSION['Access_List']中
$_SESSION['Access_List'] = $this->get_access($uid);
if(!empty($_GET['m'])){
//判断此控制器是否被允许
if(array_key_exists($_GET['m'],$_SESSION['Access_List'])){
//判断此控制器的方法是否被允许
if(in_array($_GET['a'],$_SESSION['Access_List'][$_GET['m']])){
//允许的话返回真
return true;
}else{
//否则返回假
return false;
}
}else{
return false;
}
}else{
return false;
}
}else{
//$_SESSION['user_'.$uid]['Access_List'] = 0;
return false;
}
}
public function show_node(){
$path = APP_PATH.'/controls/';
$handle = opendir($path);
while(false!==($data = readdir($handle))){
if(is_file($path.$data) && $data!='common.class.php' && $data!='pub.class.php'){
$controller = str_replace(".class.php",'',$data);
$res = fopen($path.$data,'r');
$str = fread($res,filesize($path.$data));
$pattern = '/function(.*)\(\)/iU';
preg_match_all($pattern, $str, $matches);
foreach($matches[1] as $v){
$v = trim($v);
$arr[$controller][] = $v;
}
}
}
closedir($handle);
return $arr;
}
}
初始化类:
/*+---------------------------------------------------------------------------------------+
| 初始化控制器

class Common extends Action {
/*
初始化方法
*/
public function init(){
//如果SESSION为空,则跳转
if(empty($_SESSION['user_login'])){
$this->redirect("pub/index");
}
$a = new rbac();
if(!$a->check($_SESSION['user_info']['id'])){
echo "<script>alert(&#39;您没有此权限!&#39;)</script>";
exit("<script>document.write(&#39;<span style=\&#39;font-size:40px;font-weight:bold\&#39;>Access Forbidden&#39;);alert(&#39;您没有此权限!&#39;);</script>");
$this->redirect("pub/index");
}
}
}

这里给大家写了一个简单的RBAC类,仅供大家学习参考此思想,如有问题可以跟帖回复....

 


作者 zdrjlamp

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/478251.htmlTechArticle上文http://www.2cto.com/kf/201205/129972.html给大家讲解了使用循环输出九九乘法表,逻辑上还是相对简单一些,重在给大家提供一种看程序,解析...
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Configuration du projet CakePHP Configuration du projet CakePHP Sep 10, 2024 pm 05:25 PM

Dans ce chapitre, nous comprendrons les variables d'environnement, la configuration générale, la configuration de la base de données et la configuration de la messagerie dans CakePHP.

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

CakePHP travaillant avec la base de données CakePHP travaillant avec la base de données Sep 10, 2024 pm 05:25 PM

Travailler avec la base de données dans CakePHP est très simple. Nous comprendrons les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) dans ce chapitre.

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

Routage CakePHP Routage CakePHP Sep 10, 2024 pm 05:25 PM

Dans ce chapitre, nous allons apprendre les sujets suivants liés au routage ?

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

CakePHP créant des validateurs CakePHP créant des validateurs Sep 10, 2024 pm 05:26 PM

Le validateur peut être créé en ajoutant les deux lignes suivantes dans le contrôleur.

See all articles