1. 簡介
Auth權限管理比RBAC更加靈活,auth對權限的控制更為精細。
Auth的特性:
- 是對規則進行認證,不是對節點進行認證。使用者可以把節點當作規則名稱實作對節點進行認證。 auth=newAuth(); auth->check(‘規則名稱’,’使用者id’)
- 可以同時對多條規則進行認證,并設定多條規則的關系(or或者and)。 auth=newAuth(); auth->check(‘規則1,規則2’,’使用者id’,’and’)
- 一個使用者可以屬于多個使用者組(think_auth_group_access表 定義了使用者所屬使用者組),我們需要設定每個使用者組擁有哪些規則(think_auth_group 定義了使用者組的權限)。
- 支援規則表達式。在think_auth_rule 表中定義一條規則時,如果type為1, condition字段就可以定義規則表達式。 如定義{score}>50 and {score}<100 表示使用者的分數在50-100之間時這條規則才會通過。
2. 基本用法
以ThinkPHP3.2.3為例,進行簡單介紹。
Auth類檔案為ThinkPHP\Library\Think\Auth.class.php,預設的認證方式為實時認證。
建立四張資料表。
# 使用者表
CREATE TABLE IF NOT EXISTS `think_user` (
`uid` mediumint() unsigned NOT NULL AUTO_INCREMENT COMMENT '使用者id',
`username` varchar() NOT NULL DEFAULT '' COMMENT '使用者名',
`password` char() NOT NULL DEFAULT '' COMMENT '密碼',
`status` tinyint() unsigned NOT NULL DEFAULT COMMENT '狀态:0禁用,1正常',
`score` mediumint() unsigned NOT NULL DEFAULT COMMENT '積分',
`login_time` int() unsigned NOT NULL DEFAULT COMMENT '最近一次登入時間',
`login_ip` int() NOT NULL DEFAULT '0' COMMENT '最近一次登入ip',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='使用者表';
# 使用者-使用者組關系表
CREATE TABLE IF NOT EXISTS `think_auth_group_access` (
`uid` mediumint() unsigned NOT NULL DEFAULT COMMENT '使用者id',
`group_id` mediumint() unsigned NOT NULL DEFAULT COMMENT '組id',
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='使用者-使用者組關系表';
# 規則表
CREATE TABLE IF NOT EXISTS `think_auth_rule` (
`id` mediumint() unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` char() NOT NULL DEFAULT '' COMMENT '規則的唯一辨別(英文)',
`title` char() NOT NULL DEFAULT '' COMMENT '規則的中文名稱',
`type` tinyint() NOT NULL DEFAULT '1',
`status` tinyint() NOT NULL DEFAULT '1' COMMENT '狀态:1正常,0禁用',
`condition` char() NOT NULL DEFAULT '' COMMENT '規則的附加條件',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='規則表';
# 使用者組表
CREATE TABLE IF NOT EXISTS `think_auth_group` (
`id` mediumint() unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`title` char() NOT NULL DEFAULT '' COMMENT '使用者組的中文名稱',
`status` tinyint() NOT NULL DEFAULT '1' COMMENT '狀态:0禁用,1正常',
`rules` char() NOT NULL DEFAULT '' COMMENT '使用者組擁有的規則id, 多個規則用,隔開',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT '使用者組表';
子產品配置檔案D:\xampp\htdocs\test\Application\Adm\Conf\config.php的代碼如下:
<?php
return array(
//'配置項'=>'配置值'
// 資料庫配置
'DB_TYPE' => 'mysql', // 資料庫類型
'DB_HOST' => '127.0.0.1', // 伺服器位址
'DB_NAME' => 'auth', // 資料庫名
'DB_USER' => 'root', // 使用者名
'DB_PWD' => '123456', // 密碼
'DB_PORT' => '3306', // 端口
'DB_PREFIX' => 'think_', // 資料庫表字首
// auth權限驗證的配置
'AUTH_CONFIG' => array(
'AUTH_ON' => true, // 認證開關
'AUTH_TYPE' => , // 認證方式:1為實時認證,2為登入認證。
'AUTH_GROUP' => 'think_auth_group', // 使用者組表
'AUTH_GROUP_ACCESS' => 'think_auth_group_access', // 使用者-使用者組關系表
'AUTH_RULE' => 'think_auth_rule', // 權限規則表
'AUTH_USER' => 'think_user', // 使用者表
),
);
測試資料如下:
使用者表(think_user):
uid | username | password | status | score | login_time | login_ip |
---|---|---|---|---|---|---|
1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 | |||
2 | user01 | e10adc3949ba59abbe56e057f20f883e | 1 | |||
3 | user02 | e10adc3949ba59abbe56e057f20f883e | 1 | 60 | 1497321747 | 2130706433 |
規則表(think_auth_rule):
id | name | title | type | status | condition |
---|---|---|---|---|---|
1 | adm/index/index | 背景首頁 | 1 | 1 | |
2 | adm/index/test | 測試頁面 | 1 | 1 | {score}>50 and {score}<100 |
使用者組表(think_auth_group)
id | title | status | rules |
---|---|---|---|
1 | 普通會員 | 1 | 1 |
2 | 黃金會員 | 1 | 1,2 |
使用者-使用者組關系表(think_auth_group_access)
uid | group_id |
---|---|
2 | 1 |
3 | 2 |
D:\xampp\htdocs\test\Application\Adm\Controller\PublicController.class.php的代碼如下:
<?php
namespace Adm\Controller;
use Think\Controller;
class PublicController extends Controller {
/**
* 使用者登入頁面
* http://127.0.0.1/test/index.php/public/login
*/
public function login() {
$this->display();
}
/**
* 登入送出的位址
*/
public function login_submit() {
if(!IS_POST) $this->error('頁面不存在,請稍後再試', U('Public/login'));
$username = I('username','');
$password = I('password','');
$user_info = M('user')->where("username = '$username' AND password = '".md5($password)."'")->find();
if(!$user_info) $this->error('使用者名或密碼錯誤', U('Public/login'));
if(!$user_info['status']) $this->error('該使用者已被禁用,暫時不可登入', U('Public/login'));
// 更新登入資訊
M('user')->save(array("uid"=> $user_info["uid"], "login_time"=> time(), "login_ip" => ip2long(get_client_ip())));
// 寫入session
session('uid', $user_info['uid']); // 使用者id(uid)
session('username', $user_info['username']); // 使用者名
$this->success('登入成功', U('Index/index'));
}
}
D:\xampp\htdocs\test\Application\Adm\Controller\CommonController.class.php的代碼如下:
<?php
namespace Adm\Controller;
use Think\Controller;
/**
* @author Administrator
* 所有需要進行權限驗證的控制器,使其繼承CommonController即可
*/
class CommonController extends Controller {
/**
* ThinkPHP中提供了_initialize()方法,在類初始化時,_initialize()方法會自動執行
*/
protected function _initialize() {
// 執行個體化auth對象
$auth = new \Think\Auth();
$rule_name = strtolower(MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME);
// 驗證權限
$res = $auth->check($rule_name, $_SESSION['uid']);
if($res === false) $this->error('您沒有權限通路!', U('Public/login'));
}
}
D:\xampp\htdocs\test\Application\Adm\Controller\IndexController.class.php的代碼如下:
<?php
namespace Adm\Controller;
/**
* @author Administrator
* 需要進行auth權限驗證的控制器就繼承CommonController
*/
class IndexController extends CommonController {
/**
* 背景首頁
* http://127.0.0.1/test/index.php/index/index
*/
public function index() {
dump(session());
echo '背景首頁!';
}
/**
* 測試頁面
* http://127.0.0.1/test/index.php/index/test
*/
public function test() {
echo MODULE_NAME.'<br/>';
echo CONTROLLER_NAME.'<br/>';
echo ACTION_NAME.'<br/>';
echo '這是測試頁面';
}
}