ThinkPHP Authority Authentication Auth Instance Detailed Explanation

  • 2021-07-09 07:42:51
  • OfStack

In this paper, the implementation principle and method of ThinkPHP authority authentication Auth are deeply analyzed in the form of example code. The specific steps are as follows:

mysql database part sql code:


-- ----------------------------
-- Table structure for think_auth_group
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_group`;
CREATE TABLE `think_auth_group` (
 `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
 `title` char(100) NOT NULL DEFAULT '',
 `status` tinyint(1) NOT NULL DEFAULT '1',
 `rules` char(80) 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 ' Users id',
 `group_id` mediumint(8) unsigned 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=' List of User Groups ';

-- ----------------------------
-- Records of think_auth_group_access
-- ----------------------------
INSERT INTO `think_auth_group_access` VALUES ('1', '1');
INSERT INTO `think_auth_group_access` VALUES ('1', '2');

-- ----------------------------
-- Table structure for think_auth_rule
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_rule`;
CREATE TABLE `think_auth_rule` (
 `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
 `name` char(80) NOT NULL DEFAULT '' COMMENT ' Rule only 1 Identification ',
 `title` char(20) NOT NULL DEFAULT '' COMMENT ' Chinese name of rule ',
 `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT ' Status: Is 1 Normal, for 0 Disable ',
 `type` char(80) NOT NULL,
 `condition` char(100) NOT NULL DEFAULT '' COMMENT ' Regular expression, if it is null, it will be verified if it exists, and if it is not null, it will be verified according to conditions ',
 PRIMARY KEY (`id`),
 UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT=' Rule 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(11) NOT NULL,
 `username` varchar(30) DEFAULT NULL,
 `password` varchar(32) 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(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

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();
  // List of rules to validate , Support comma-separated permission rules or indexed arrays 
  $name = MODULE_NAME . '/' . ACTION_NAME;
  // Current user id
  $uid = '1';
  // Classification 
  $type = MODULE_NAME;
  // Execute check Mode of 
  $mode = 'url';
  //'or'  Satisfy any 1 Rule is verified ;
  //'and' It means that all rules need to be met to pass the validation 
  $relation = 'and';
  if ($Auth->check($name, $uid, $type, $mode, $relation)) {
   die(' Certification: Successful ');
  } else {
   die(' Certification: Failure ');
  }
 }
}

These codes are the most basic examples of validation code.

The following is the source code reading:

1. Initialization configuration information of permission verification class:


$Auth = new \Think\Auth();

The program merges configuration information when creating 1 object
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')) {
   // Configuration items can be set  AUTH_CONFIG,  This configuration item is an array. 
   $this->_config = array_merge($this->_config, C('AUTH_CONFIG'));
  }
 }

2. Check permissions:


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

General analysis of this method under 1

First, determine whether to turn off permission verification. If the configuration information AUTH_ON= > false does not validate permissions otherwise continue validating permissions


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

After obtaining the permission list, it will be described in detail:


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

The list of rules to be verified this time is converted into an array:


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

Therefore, the $name parameter 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)));
}

The first core code segment of permission verification, that is, cycling all the user permissions to determine whether the permissions to be verified are in the user authorization list:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

0

in_array ($auth, $name) Add to $list if one of the permissions in the permission list is equal to the permissions currently to be verified
Note:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

1

3. Get the permission list:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

2

This main process:

Get User Groups


$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.status='1' )

The simplified operation is:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

4

Obtain the user group rules rule field. This field stores the id of the think_auth_rule rule table. Split

The $ids is the id array to which the $groups variable is finally converted:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

5

Gets the rule information in the think_auth_rule table and then loops:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

6

It can be seen here that getUserInfo will get the table name corresponding to the configuration file AUTH_USER to find the user information

The key points are:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

7

'/\ {(\ w*?)\}/Think of the text to be matched as {string} then {string} will be replaced with $user [' string ']
$command = $user ['string ']

If


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

Namely:


<?php

return array(
 //' Configuration item '=>' Configuration value '
 'DB_DSN' => '', //  Database connection DSN  Used for PDO Mode 
 'DB_TYPE' => 'mysql', //  Database type 
 'DB_HOST' => 'localhost', //  Server address 
 'DB_NAME' => 'thinkphp', //  Database name 
 'DB_USER' => 'root', //  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 method, 1 Authenticated from time to time; 2 Authenticate for login. 
  'AUTH_GROUP' => 'think_auth_group', // User group datasheet name 
  'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // List of User Groups 
  'AUTH_RULE' => 'think_auth_rule', // Permission rule table 
  'AUTH_USER' => 'think_user'// User information table 
 )
);

9

At this time, look at the following code again. If it is true, it will be added as an authorization list


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

Readers who are interested in thinkPHP can check the topics of this site: "ThinkPHP Introduction Tutorial", "thinkPHP Template Operation Skills Summary", "ThinkPHP Common Methods Summary", "smarty Template Introduction Basic Tutorial" and "PHP Template Technology Summary".

I hope this article is helpful to the PHP programming based on ThinkPHP framework.


Related articles: