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 '这是测试页面';
}
}