- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章ThinkPHP权限认证Auth实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文以实例代码的形式深入剖析了ThinkPHP权限认证Auth的实现原理与方法,具体步骤如下:
mysql数据库部分sql代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
-- ----------------------------
-- 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=
'用户组表'
;
-- ----------------------------
-- Records of think_auth_group
-- ----------------------------
INSERT
INTO
`think_auth_group`
VALUES
(
'1'
,
'管理组'
,
'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
'用户id'
,
`group_id` mediumint(8) unsigned
NOT
NULL
COMMENT
'用户组id'
,
UNIQUE
KEY
`uid_group_id` (`uid`,`group_id`),
KEY
`uid` (`uid`),
KEY
`group_id` (`group_id`)
) ENGINE=MyISAM
DEFAULT
CHARSET=utf8 COMMENT=
'用户组明细表'
;
-- ----------------------------
-- 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
'规则唯一标识'
,
`title`
char
(20)
NOT
NULL
DEFAULT
''
COMMENT
'规则中文名称'
,
`status` tinyint(1)
NOT
NULL
DEFAULT
'1'
COMMENT
'状态:为1正常,为0禁用'
,
`type`
char
(80)
NOT
NULL
,
`condition`
char
(100)
NOT
NULL
DEFAULT
''
COMMENT
'规则表达式,为空表示存在就验证,不为空表示按照条件验证'
,
PRIMARY
KEY
(`id`),
UNIQUE
KEY
`
name
` (`
name
`)
) ENGINE=MyISAM AUTO_INCREMENT=5
DEFAULT
CHARSET=utf8 COMMENT=
'规则表'
;
-- ----------------------------
-- Records of think_auth_rule
-- ----------------------------
INSERT
INTO
`think_auth_rule`
VALUES
(
'1'
,
'Home/index'
,
'列表'
,
'1'
,
'Home'
,
''
);
INSERT
INTO
`think_auth_rule`
VALUES
(
'2'
,
'Home/add'
,
'添加'
,
'1'
,
'Home'
,
''
);
INSERT
INTO
`think_auth_rule`
VALUES
(
'3'
,
'Home/edit'
,
'编辑'
,
'1'
,
'Home'
,
''
);
INSERT
INTO
`think_auth_rule`
VALUES
(
'4'
,
'Home/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'
);
|
配置文件Application\Common\Conf\config.php部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
return
array
(
//'配置项'=>'配置值'
'DB_DSN'
=>
''
,
// 数据库连接DSN 用于PDO方式
'DB_TYPE'
=>
'mysql'
,
// 数据库类型
'DB_HOST'
=>
'localhost'
,
// 服务器地址
'DB_NAME'
=>
'thinkphp'
,
// 数据库名
'DB_USER'
=>
'root'
,
// 用户名
'DB_PWD'
=>
'root'
,
// 密码
'DB_PORT'
=> 3306,
// 端口
'DB_PREFIX'
=>
'think_'
,
// 数据库表前缀
'AUTH_CONFIG'
=>
array
(
'AUTH_ON'
=> true,
//认证开关
'AUTH_TYPE'
=> 1,
// 认证方式,1为时时认证;2为登录认证。
'AUTH_GROUP'
=>
'think_auth_group'
,
//用户组数据表名
'AUTH_GROUP_ACCESS'
=>
'think_auth_group_access'
,
//用户组明细表
'AUTH_RULE'
=>
'think_auth_rule'
,
//权限规则表
'AUTH_USER'
=>
'think_user'
//用户信息表
)
);
|
项目Home控制器部分Application\Home\Controller\IndexController.class.php代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
namespace
Home\Controller;
use
Think\Controller;
class
IndexController
extends
Controller {
public
function
index() {
$Auth
=
new
\Think\Auth();
//需要验证的规则列表,支持逗号分隔的权限规则或索引数组
$name
= MODULE_NAME .
'/'
. ACTION_NAME;
//当前用户id
$uid
=
'1'
;
//分类
$type
= MODULE_NAME;
//执行check的模式
$mode
=
'url'
;
//'or' 表示满足任一条规则即通过验证;
//'and'则表示需满足所有规则才能通过验证
$relation
=
'and'
;
if
(
$Auth
->check(
$name
,
$uid
,
$type
,
$mode
,
$relation
)) {
die
(
'认证:成功'
);
}
else
{
die
(
'认证:失败'
);
}
}
}
|
以上这些代码就是最基本的验证代码示例.
下面是源码阅读:
1、权限检验类初始化配置信息:
1
|
$Auth
=
new
\Think\Auth();
|
创建一个对象时程序会合并配置信息 程序会合并Application\Common\Conf\config.php中的AUTH_CONFIG数组 。
1
2
3
4
5
6
7
8
9
10
11
|
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'
)) {
//可设置配置项 AUTH_CONFIG, 此配置项为数组。
$this
->_config =
array_merge
(
$this
->_config, C(
'AUTH_CONFIG'
));
}
}
|
2、检查权限:
1
|
check(
$name
,
$uid
,
$type
= 1,
$mode
=
'url'
,
$relation
=
'or'
)
|
大体分析一下这个方法 。
首先判断是否关闭权限校验 如果配置信息AUTH_ON=>false 则不会进行权限验证 否则继续验证权限 。
1
2
3
|
if
(!
$this
->_config[
'AUTH_ON'
]) {
return
true;
}
|
获取权限列表之后会详细介绍:
1
|
$authList
=
$this
->getAuthList(
$uid
,
$type
);
|
此次需要验证的规则列表转换成数组:
1
2
3
4
5
6
7
8
|
if
(
is_string
(
$name
)) {
$name
=
strtolower
(
$name
);
if
(
strpos
(
$name
,
','
) !== false) {
$name
=
explode
(
','
,
$name
);
}
else
{
$name
=
array
(
$name
);
}
}
|
所以$name参数是不区分大小写的,最终都会转换成小写 。
开启url模式时全部转换为小写:
1
2
3
|
if
(
$mode
==
'url'
) {
$REQUEST
= unserialize(
strtolower
(serialize(
$_REQUEST
)));
}
|
权限校验核心代码段之一,即循环所有该用户权限 判断 当前需要验证的权限 是否 在用户授权列表中:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
foreach
(
$authList
as
$auth
) {
$query
= preg_replace(
'/^.+\?/U'
,
''
,
$auth
);
//获取url参数
if
(
$mode
==
'url'
&&
$query
!=
$auth
) {
parse_str
(
$query
,
$param
);
//获取数组形式url参数
$intersect
=
array_intersect_assoc
(
$REQUEST
,
$param
);
$auth
= preg_replace(
'/\?.*$/U'
,
''
,
$auth
);
//获取访问的url文件
if
(in_array(
$auth
,
$name
) &&
$intersect
==
$param
) {
//如果节点相符且url参数满足
$list
[] =
$auth
;
}
}
else
if
(in_array(
$auth
,
$name
)) {
$list
[] =
$auth
;
}
}
|
in_array($auth, $name) 如果 权限列表中 其中一条权限 等于 当前需要校验的权限 则加入到$list中 注:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$list
=
array
();
//保存验证通过的规则名
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
);
//当or时 只要有一条是通过的 则 权限为真
$relation
==
'and'
and
empty
(
$diff
);
//当and时 $name与$list完全相等时 权限为真
|
3、获取权限列表:
1
|
$authList
=
$this
->getAuthList(
$uid
,
$type
);
//获取用户需要验证的所有有效规则列表
|
这个主要流程:
获取用户组 。
1
2
|
$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' )
|
简化操作就是:
1
|
SELECT
`rules`
FROM
think_auth_group
WHERE
STATUS =
'1'
AND
id=
'1'
//按正常流程 去think_auth_group_access表中内联有点多余....!
|
取得用户组rules规则字段 这个字段中保存的是think_auth_rule规则表的id用,分割 。
$ids就是$groups变量最终转换成的 id数组:
1
2
3
4
5
|
$map
=
array
(
'id'
=>
array
(
'in'
,
$ids
),
'type'
=>
$type
,
'status'
=> 1,
);
|
取得think_auth_rule表中的规则信息,之后循环:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
foreach
(
$rules
as
$rule
) {
if
(!
empty
(
$rule
[
'condition'
])) {
//根据condition进行验证
$user
=
$this
->getUserInfo(
$uid
);
//获取用户信息,一维数组
$command
= preg_replace(
'/\{(\w*?)\}/'
,
'$user[\'\\1\']'
,
$rule
[
'condition'
]);
//dump($command);//debug
@(
eval
(
'$condition=('
.
$command
.
');'
));
if
(
$condition
) {
$authList
[] =
strtolower
(
$rule
[
'name'
]);
}
}
else
{
//只要存在就记录
$authList
[] =
strtolower
(
$rule
[
'name'
]);
}
}
if
(!
empty
(
$rule
[
'condition'
])) {
//根据condition进行验证
|
这里就可以明白getUserInfo 会去获取配置文件AUTH_USER对应表名 去查找用户信息 。
重点是:
1
2
|
$command
= preg_replace(
'/\{(\w*?)\}/'
,
'$user[\'\\1\']'
,
$rule
[
'condition'
]);
@(
eval
(
'$condition=('
.
$command
.
');'
));
|
'/\{(\w*?)\}/ 可以看成要匹配的文字为 {字符串} 那么 {字符串} 会替换成$user['字符串'] $command =$user['字符串'] 。
如果 。
1
2
3
4
5
|
$rule
[
'condition'
] =
'{age}'
;
$command
=
$user
[
'age'
]
$rule
[
'condition'
] =
'{age} > 5'
;
$command
=
$user
[
'age'
] > 10
@(
eval
(
'$condition=('
.
$command
.
');'
));
|
即:
1
|
$condition
=(
$user
[
'age'
] > 10);
|
这时再看下面代码 如果为真则加为授权列表 。
1
2
3
|
if
(
$condition
) {
$authList
[] =
strtolower
(
$rule
[
'name'
]);
}
|
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助.
最后此篇关于ThinkPHP权限认证Auth实例详解的文章就讲到这里了,如果你想了解更多关于ThinkPHP权限认证Auth实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
thinkphp开发图片上传,图片异步上传是目前比较方便的功能,这里我就不写css文件了,将代码写出来。引入核心文件下载https://github.com/carlcarl/A... HTML
现在谁不开发接口的呢?但是在接口开发过程中,报错误html">异常后居然返回错误的信息依然是html信息!TP官方也不知道为啥不添加,说好的为接口而生,我的解决方案也很简单,把系统的
thinkphp 抓取网站的内容并且保存到本地的实例详解 我需要写这么一个例子,到电子课本网下载一本电子书。 电子课本网的电子书,是把书的每一页当成一个图片,然后一本书就是有很多张图片,我需要批
假设数据库中会计科目数据表的字段为:id,code,name,islast。分别为自增主键,科目编码,科目名称,是否为末级("1"表示末级科目)。 这里在Thinkphp的模型
本文实例讲述了thinkphp+phpexcel实现excel报表输出功能。分享给大家供大家参考,具体如下: 准备工作: 1.下载phpexcel1.7.6类包; 2.解压至tp框架的thin
ThinkPHP 内置的模板引擎来定义模板文件,以及使用加载文件、模板布局和模板继承等高级功能。 每个模板文件在执行过程中都会生成一个编译后的缓存文件,其实就是一个可以运行的 PHP 文件。 引
本文实例讲述了thinkPHP+ajax实现统计页面pv浏览量的方法。分享给大家供大家参考,具体如下: 统计pv量很常用,下面的代码用ajax实现的,使用ajax可以避免页面缓存造成的影响,只要客
在很多网站中都会有使用404页面的时候,在ThinkPHP框架中该如何设置呢,接下来我介绍其中一种方法 1、首先要在Lib/Action 下建立EmptyAction.class.php模块 内容
话不多说,请看代码: ? 1
ThinkPHP 模板substr的截取字符串函数 在Common/function.php加上以下代码 ?
先上效果图: 那个file按钮样式先忽略 点击选择图片(浏览),随便选一张图片 js代码如下 ?
本文实例分析了thinkPHP js文件中U方法不被解析问题。分享给大家供大家参考,具体如下: 我想在js文件中写ajax, 写完发现异常, 本以为是js文件中不支持ajax 后来发现时地址
使用TP 3.2框架 ? 1
本文实例讲述了thinkphp,onethink和thinkox中验证码不显示的解决方法。分享给大家供大家参考,具体如下: 使用验证码的时候,一开始正常,后来不显示了 网上说是utf-8的编码问
1、基础知识 1.手机APP的类型 移动端的应用有这几种:WebApp,NativeApp,HybridApp。 WebApp 就是手机网站,需要用手机浏览器访问。 NativeApp是用
ThinkPHP CURD操作的查询方法中最常用但也是最复杂的就是where方法。where方法也属于模型类的连贯操作方法之一,主要用于查询和操作条件的设置。 where方法的用法是ThinkPH
ThinkPHP CURD方法的limit方法也是模型类的连贯操作方法之一,主要用于指定查询和操作的数量,特别在分页查询的时候使用较多。并且ThinkPHP的limit方法可以兼容所有的数据库驱动类
ThinkPHP CURD方法的page方法也是模型连贯操作方法之一,是完全为分页查询而诞生的一个人性化操作方法。 用法 我们在前面已经分析了关于limit方法用于分页查询的情况,而page方法则
ThinkPHP CURD方法的table方法也属于模型类的连贯操作方法之一,该方法主要用于指定操作的数据表。 具体用法如下: 一般情况下,操作模型的时候系统能够自动识别当前对应的数据表,所以,
ThinkPHP CURD方法的order方法属于模型的连贯操作方法之一,该方法用于对操作的结果排序。 具体用法如下: ?
我是一名优秀的程序员,十分优秀!