PHP 7-Role-Based Access Control RBAC

Source: Internet
Author: User

Above ....

Well, I will not talk about it much. This article will introduce you to "Role-Based Access Control ",

When it comes to permissions, It is a headache for everyone. How can we flexibly control the permissions of a user,

Some students add fields in the User table or add corresponding permission fields in the role table,

This may cause a problem. It may feel very bad to start with permissions, and it is not flexible. Every time you add a permission, you must add a field to the database, which is not conducive to iterative development of the project.

In this case, we need a flexible design model RBAC, namely Role-Based Access Control;

Let me introduce this design idea to you:

First, we need to determine whether a user has permission to access the Controller or Controller Method of the current operation,

If multiple users have the same permissions at the same time, we need to specify the same user role for these users, and then only need to use the role to control the access permissions of the operation,

We need to design the table structure as follows:

The first data table (User table ):
 

Field name Field description
Id User ID (primary key auto-increment)
Username User Name
Password User Password
 

The second data table (role table ):
 

Field name Field description
Id User Role ID (primary key auto-increment)
Name User role name
   
 

The third data table (node table ):
 

Field name Field description
Id Operation node ID (primary key auto-increment)
Name Name of the Operation Node
Zh_name Node description
 

We use the third paradigm to design associated tables. The advantage of doing so is to avoid data redundancy and to clearly record and organize one-to-many and many-to-one relationships.

The fourth data table (role table corresponding to the node ):
 

Field name Field description
Role_id User Role ID (foreign key, primary key ID in the associated role table)
Note_id Operation node ID (foreign key, primary key ID in the associated node table)
   
 

The fifth data table (role table ):
 

Field name Field description
Role_id User Role ID (foreign key, primary key ID in the associated role table)
User_id User ID (foreign key, associated with the primary key ID in the User table)
   
 

You can use these five tables to control the access permissions. The procedure is as follows:

Enter the user name and password to log on,
Based on the user table, if the user name and password entered are illegal, the user jumps back to log on again.
If it is valid, the user ID is returned in the User table,
This user ID is used to query the user's role ID in the user-role Association table,
Obtain the role ID and use this ID to query the node access permissions of this role in the association table between the role and the node,
This permission node is all stored in the SESSION. When a user accesses a module,

Example: http://www.lampbroher.net/index.php/stu/index

We use the permissions in the session to compare with $ _ GET ['M'] and $ _ GET ['a,

If $ _ GET ['M'] or $ _ GET ['a'] does not exist in the SESSION, the user does not have this permission and can process it.

Reference code:

RBAC files:
<? Php
/* + Response +
| RBAC permission Control

Class Rbac {
Private $ node_tablename; // defines the name of the private attribute node table.
Private $ group_auth_tablename; // defines the name of the permission table of the private property group.
Private $ group_tablename; // defines the table name of the user group with private attributes.
Private $ group_user_tablename; // defines the name of the table in which the user belongs to the group.
Private $ user_tablename; // defines the name of the user table with private attributes.
/*
Constructor
@ Param1 string node table name
@ Param2 string user permission table name
@ Param3 string user group table name
@ Param4 string name of the user group table
@ Param5 string User table name
*/
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; // obtain the node table name.
$ This-> group_auth_tablename = $ group_auth_tablename; // obtain the user permission table name
$ This-> group_tablename = $ group_tablename; // obtain the table name of the user group.
$ This-> group_user_tablename = $ group_user_tablename; // obtain the table name of the user group.
$ This-> user_tablename = $ user_tablename; // get the user table name
}
/*
Node setting method
@ Param1 string node name
@ Param2 string node parent ID
@ Param2 string node description
@ Return int ID after the node record is inserted successfully
*/
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;
}
/*
How to Set permissions
@ Param1 int group ID
@ Param2 int node ID
@ Return int ID after successful permission record insertion
*/
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;
}
/*
Obtain a node
@ Param1 int node ID
@ Return array: obtains information about the node table.
*/
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;
}
}
/*
Methods for obtaining Group Permissions
@ Param1 int user group ID
@ Return array: obtains information about the group permission table.
*/
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;
}
}
/*
Getting user groups
@ Param1 int user ID
@ Return array get the user group id corresponding to the user
*/
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;
}
}
/*
Obtain the subnode method of a node
@ Param1 int node ID
@ Return array: obtains all the subnodes corresponding to the node.
*/
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;
}
}
/*
How to obtain permissions
@ Param1 int user ID
@ Return array get permission list
*/
Public function get_access ($ uid ){
If (! Empty ($ uid )){
// Call the method for obtaining group information
$ Group = $ this-> get_group ($ uid );
// Traverse group information
Foreach ($ group as $ v ){
// Pass in the group ID to obtain the permission
$ Auth = $ this-> get_auth ($ v ['gid']); // obtain the permissions of this group
}
// Traverse the permission array of the Group
Foreach ($ auth as $ val ){
// Pass in the node ID to obtain the node Information
$ Node [] = $ this-> get_node ($ val ['nid']); // obtain node Information
}
// Traverse the node array and assemble it
Foreach ($ node as $ nval ){
If ($ nval ['pid '] = 0 ){
$ Fnode [] = $ nval; // press the controller into the fnode Array
// $ Cnode = $ this-> get_cnode ($ nval ['id']);
} Else {
$ Cnode [] = $ nval; // press the Controller method into the cnode Array
}
}
// Assemble the Controller array and controller array into an array
Foreach ($ fnode as $ fval ){
Foreach ($ cnode as $ cval ){
If ($ cval ['pid '] ==$ fval ['id']) {
$ Access [$ fval ['name'] [] = $ cval ['name'];
}
}
}
// Returns the permission list Array
Return $ access;
} Else {
Return false;
}
}
/*
Permission Detection Method
@ Param1 int user ID
@ Return boolean: whether the permission is disabled or not
*/
Public function check ($ uid ){
If (! Empty ($ uid )){
// Save the permission to $ _ SESSION ['Access _ list ']
$ _ SESSION ['Access _ list'] = $ this-> get_access ($ uid );
If (! Empty ($ _ GET ['M']) {
// Determine whether the controller is allowed
If (array_key_exists ($ _ GET ['M'], $ _ SESSION ['Access _ list']) {
// Determine whether the method of this controller is allowed
If (in_array ($ _ GET ['a'], $ _ SESSION ['Access _ list'] [$ _ GET ['M']) {
// Returns true if allowed
Return true;
} Else {
// Otherwise, false is returned.
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;
}
}
Initialization class:
<? Php
/* + Response +
| Initialize the Controller

Class Common extends Action {
/*
Initialization Method
*/
Public function init (){
// Jump if the SESSION is empty
If (empty ($ _ SESSION ['user _ login']) {
$ This-> redirect ("pub/index ");
}
$ A = new rbac ();
If (! $ A-> check ($ _ SESSION ['user _ info'] ['id']) {
Echo "<script> alert ('you do not have this permission! ') </Script> ";
Exit ("<script> document. write ('<span style = \' font-size: 40px; font-weight: bold \ '> Access Forbidden'); alert ('you do not have this permission! '); </Script> ");
$ This-> redirect ("pub/index ");
}
}
}

Here we have written a simple RBAC class for you to learn and reference this idea. If you have any questions, please reply with me ....

 


Author: zdrjlamp

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.