thinkphp Permission Authentication Auth instance Detailed _php example

Source: Internet
Author: User
Tags auth diff eval lowercase php template unique id smarty template

This paper analyzes the implementation principle and method of thinkphp authorization auth in the form of instance code, the following steps are as follows:

MySQL database part of SQL code:

--------------------------------Table structure for think_auth_group------------------------------DROP Table IF EXI
STS ' Think_auth_group ';  CREATE TABLE ' Think_auth_group ' (' ID ' mediumint (8) unsigned not NULL auto_increment, ' title ' char (m) NOT null DEFAULT  ', ' status ' tinyint (1) NOT null default ' 1 ', ' rules ' char ' is not null default ', PRIMARY KEY (' id ') Engine=myisam

auto_increment=2 DEFAULT Charset=utf8 comment= ' user Group table '; --------------------------------Records of Think_auth_group------------------------------INSERT into ' think_auth_

Group ' VALUES (' 1 ', ' Management Group ', ' 1 ', ' 1,2 '); --------------------------------Table structure for think_auth_group_access------------------------------DROP
TABLE IF EXISTS ' think_auth_group_access '; CREATE TABLE ' think_auth_group_access ' (' UID ' mediumint (8) unsigned not NULL COMMENT ' user ID ', ' group_id ' mediumint (8) UN Signed not NULL COMMENT ' user group ID ', UNIQUE key ' uid_group_id ' (' uid ', ' group_id '), key ' uid ' (' uid '), key ' Group_id ' (' group_id ') engine=myisam DEFAULT charset=utf8 comment= ' user Group Schedule '; --------------------------------Records of think_auth_group_access------------------------------INSERT into '
_auth_group_access ' VALUES (' 1 ', ' 1 ');

INSERT into ' think_auth_group_access ' VALUES (' 1 ', ' 2 '); --------------------------------Table structure for think_auth_rule------------------------------DROP Table IF EXIST
S ' Think_auth_rule ';  CREATE TABLE ' think_auth_rule ' (' ID ' mediumint (8) unsigned not NULL auto_increment, ' name ' char ' is not null DEFAULT ' COMMENT ' rule unique ID ', ' title ' char ' NOT null default ' COMMENT ' rule Chinese name ', ' status ' tinyint (1) NOT null default ' 1 ' comme NT ' status: 1 normal, 0 disabled ', ' type ' char (not NULL, ' condition ' char (m) not null DEFAULT ' COMMENT ' rule expression, NULL to indicate existence on validation, no null representation follow bar Piece validation ', PRIMARY key (' id '), UNIQUE key ' name ' (' name ') Engine=myisam auto_increment=5 DEFAULT charset=utf8 comment= ' rules table '

; --------------------------------Records of Think_auth_rule------------------------------INSERT into ' think_auth_rule ' VALUES (' 1 ', ' home/index ', ' list ', ' 1 ', ' home ', ');
INSERT into ' think_auth_rule ' VALUES (' 2 ', ' Home/add ', ' Add ', ' 1 ', ' home ', ');
INSERT into ' think_auth_rule ' VALUES (' 3 ', ' Home/edit ', ' edit ', ' 1 ', ' home ', ');


INSERT into ' think_auth_rule ' VALUES (' 4 ', ' home/delete ', ' delete ', ' 1 ', ' home ', ');
DROP TABLE IF EXISTS ' Think_user '; CREATE TABLE ' Think_user ' (' id ' int () NOT NULL, ' username ' varchar ' default NULL, ' password ' varchar () default

NULL, ' Age ' tinyint (2) default NULL, PRIMARY KEY (' id ')) engine=innodb default Charset=utf8; --------------------------------Records of Think_user------------------------------INSERT into ' Think_user ' VALUES (

 ' 1 ', ' admin ', ' 21232f297a57a5a743894a0e4a801fc3 ', ' 25 ');

Configuration file application\common\conf\config.php section:

<?php return

Array (
 //config item ' => ' config value '
 db_dsn ' => ',//database connection DSN used PDO
 ' db_type ' => ' MySQL ',//database type
 ' db_host ' => ' localhost ',//server address
 ' db_name ' => ' thinkphp ',//database name
 ' db_user ' => ' ro OT ',//user name
 ' db_pwd ' => ' root ',//password
 ' db_port ' => 3306,//Port ' db_prefix ' => ' ' think_ '
 ,//database table prefix 
    ' auth_config ' => array (
  ' auth_on ' => true,//authentication switch
  ' Auth_type ' => 1,//authentication mode, 1 for time certification; 2 for login authentication.
  ' Auth_group ' => ' think_auth_group ',//user group data table name
  ' auth_group_access ' => ' think_auth_group_access ',// User Group Schedule
  ' auth_rule ' => ' think_auth_rule ',//Permission rules table
  ' auth_user ' => ' think_user '/user Information sheet
 )
;

Project Home Controller Section application\home\controller\indexcontroller.class.php code:

<?php
namespace Home\controller;
Use Think\controller;
Class Indexcontroller extends Controller {public
 function index () {
  $Auth = new \think\auth ();
  A list of rules that need to be validated, which supports comma-delimited permission rules or indexed arrays
  $name = module_name. '/' . Action_name;
  Current User id
  $uid = ' 1 ';
  Classification
  $type = module_name;
  Execute check mode
  $mode = ' url ';
  ' or ' means to satisfy any rule by verification;
  ' and ' means that all rules need to be met to validate
  $relation = ' and ';
  if ($Auth->check ($name, $uid, $type, $mode, $relation)) {
   die (' Authentication: Success ');
  } else {
   die (' Authentication: Failed ');
  }
 }
}

The above code is the most basic example of validation code.

The following is the source code reading:

1. Permission Validation class initialization configuration information:

$Auth = new \think\auth ();

The program merges configuration information when an object is created
The program merges the Auth_config array in application\common\conf\config.php

 Public Function __construct () {
  $prefix = C (' Db_prefix ');
  $this->_config[' auth_group '] = $prefix. $this->_config[' Auth_group '];
  $this->_config[' auth_rule '] = $prefix. $this->_config[' Auth_rule '];
  $this->_config[' auth_user '] = $prefix. $this->_config[' Auth_User '];
  $this->_config[' auth_group_access '] = $prefix. $this->_config[' auth_group_access '];
  if (C (' Auth_config ')) {
   //can set configuration item auth_config, this configuration item is an array.
   $this->_config = Array_merge ($this->_config, C (' auth_config '));
  }
 

2, check the right:

Check ($name, $uid, $type = 1, $mode = ' url ', $relation = ' or ')

Roughly analyze This method

First, determine whether to turn off permission checksums if the configuration information Auth_on=>false does not perform permission validation or continue to verify permissions

if (! $this->_config[' auth_on ']) {return
 true;
}

The access list is described in more detail:

$authList = $this->getauthlist ($uid, $type);

The list of rules to be validated is converted to an array:

if (is_string ($name)) {
 $name = Strtolower ($name);
 if (Strpos ($name, ', ')!== false) {
 $name = explode (', ', $name);
 } else {
 $name = array ($name);
 }
}

So the $name argument is case-insensitive and will eventually be converted to lowercase


Convert all to lowercase when URL mode is turned on:

if ($mode = = ' url ') {
 $REQUEST = unserialize (Strtolower (Serialize ($_request)));


Permission Checksum is one of the core code segments that loops through all of the user's permissions to determine whether the currently required authentication is in the user authorization list:

foreach ($authList as $auth) {
 $query = preg_replace ('/^.+\?/u ', ', $auth);/get URL parameter
 if ($mode = = ' URL ' && ; $query!= $auth) {
 parse_str ($query, $param);//get array form URL parameter
 $intersect = ARRAY_INTERSECT_ASSOC ($REQUEST, $ param);
 $auth = Preg_replace ('/\?. *$/u ', ', $auth); Get access URL file
 if (In_array ($auth, $name) && $intersect = = $param) {//If the node matches and the URL parameter satisfies
  $ List[] = $auth;
 }
 } else if (In_array ($auth, $name)) {
 $list [] = $auth;
 }
}

In_array ($auth, $name) add to $list if one of the permissions in the permissions list equals the currently required checksum
Note:

$list = Array (); Save validation passed rule name

if ($relation = = ' or ' and!empty ($list)) {return
 true;
}

$diff = Array_diff ($name, $list);
if ($relation = = ' and ' and Empty ($diff)) {return
 true;
}

$relation = = ' or ' and!empty ($list); The permission is true
$relation = = ' and ' and empty ($diff) when or whenever a pass is passed;//when $name is exactly equal to $list when and

3. Get permission list:

$authList = $this->getauthlist ($uid, $type); Get a list of all valid rules that the user needs to validate

This main process:

Get user Group

$groups = $this->getgroups ($uid);
SELECT ' rules ' from think_auth_group_access a INNER JOIN think_auth_group g on a.group_id=g.id WHERE (a.uid= ' 1 ' and G.S tatus= ' 1 ')

The simplified operation is:

SELECT ' rules ' from think_auth_group where STATUS = ' 1 ' and id= ' 1 '///in the normal process to think_auth_group_access the table inline is a bit superfluous ...!

Get the user Group Rules rule field This field is saved with the ID of the Think_auth_rule rule table, split

$ids is the $groups variable that is eventually converted into an array of IDs:

$map = Array ('
 ID ' => array (' in ', $ids),
 ' type ' => $type,
 ' status ' => 1,
);

Get the rule information in the Think_auth_rule table, and then loop:

foreach ($rules as $rule) {
  if (!empty ($rule [' condition '])) {//verified against condition
  $user = $this->getuserinfo ($ UID); Get user information, one-dimensional array
  $command = Preg_replace ('/\{(\w*?) \}/', ' $user [\ ' \\1\ '] ', $rule [' condition ']);
  Dump ($command);//debug
  @ (eval (' $condition = ('. $command. ');'));
  if ($condition) {
   $authList [] = Strtolower ($rule [' name ']);
  }
  {else {
  //As long as there is a record
  $authList [] = Strtolower ($rule [' name ']);
  }
if (!empty ($rule [' condition ']) {//validated according to condition

Here you can see GetUserInfo will go to get the configuration file auth_user the corresponding table name to find the user information

The point is:

$command = Preg_replace ('/\{\w*?) \}/', ' $user [\ ' \\1\ '] ', $rule [' condition ']);
@ (eval (' $condition = ('. $command. ');'));

'/\{(\w*?) \}/can be considered to match the text is {string} then {string} will be replaced by $user[' string ']
$command = $user [' String ']

If

$rule [' condition '] = ' {age} ';
$command = $user [' Age ']
$rule [' condition '] = ' {age} > 5 ';
$command = $user [' age '] >
@ (eval (' $condition = '. $command. ');'));

That

$condition = ($user [' age '] > 10);

Then look at the following code if it is true add the authorization list

if ($condition) {
  $authList [] = Strtolower ($rule [' name ']);
}

More interested in thinkphp related content readers can view the site topics: "thinkphp Introductory Course", "thinkphp Template Operation Skills Summary", "thinkphp Common Methods Summary", "Smarty Template Introductory Course" and "PHP template technology Summary."

I hope this article will help you with the PHP program design based on thinkphp framework.

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.