thinkPHP3.2使用RBAC实现权限管理的实现
在thinkphp3.2中自己集成了rbac来实现权限管理,rbac实现类在项目中地址为:thinkphp/librar/org/util/rbac.class.php,其中集成了我们所需的权限管理操作
一:表设计
在thinkphp的rbac的的rbac.class.php文件中一共提供了4张表,还有一张用户表需要你自己去建
如下是我所建的和权限相关的sql
其中的wj_为表前缀,改成你项目中的表前缀
1:权限表:
create table if not exists `wj_access` ( `role_id` smallint(6) unsigned not null comment '角色id', `node_id` smallint(6) unsigned not null comment '节点id', `level` tinyint(1) not null comment '深度', `module` varchar(50) default null comment '模块', key `groupid` (`role_id`), key `nodeid` (`node_id`) ) engine=myisam default charset=utf8 comment='权限表';
2:节点表:
create table if not exists `wj_node` ( `id` smallint(6) unsigned not null auto_increment comment '节点id', `name` varchar(20) not null comment '节点名称', `title` varchar(50) default null comment '节点标题', `status` tinyint(1) default '0' comment '状态 0禁用 1启用', `remark` varchar(255) default null comment '描述', `sort` smallint(6) unsigned default null comment '排序', `pid` smallint(6) unsigned not null comment '父级节点', `level` tinyint(1) unsigned not null comment '深度', primary key (`id`), key `level` (`level`), key `pid` (`pid`), key `status` (`status`), key `name` (`name`) ) engine=myisam default charset=utf8 comment='节点表';
3:用户角色表:
create table if not exists `wj_role` ( `id` smallint(6) unsigned not null auto_increment comment '角色id', `name` varchar(20) not null comment '角色名称', `pid` smallint(6) default null '父级id', `status` tinyint(1) unsigned default null comment '状态 0禁用 1启用', `remark` varchar(255) default null comment '备注', primary key (`id`), key `pid` (`pid`), key `status` (`status`) ) engine=myisam default charset=utf8 comment='用户角色表';
4:用户角色关联表:
create table if not exists `wj_role_user` ( `role_id` mediumint(9) unsigned default null comment '角色id', `user_id` char(32) default null comment '用户id', key `group_id` (`role_id`), key `user_id` (`user_id`) ) engine=myisam default charset=utf8 comment='用户角色关联表';
5:用户表:
create table if not exists `wj_user` ( `user_id` int(11) unsigned not null auto_increment comment '用户id', `username` varchar(50) not null comment '用户名', `password` varchar(100) not null comment '密码', `create_time` int(10) default null comment '创建时间', `update_time` int(10) default null comment '更新时间', `status` int(1) default null comment '状态 0禁用 1启用', primary key (`user_id`) ) engine=myisam default charset=utf8 comment='用户表';
二:关于权限操作的常用配置:
你可以在config.php文件的数组中增加:
// 加载扩展配置文件 'load_ext_config' => 'user',
这样的话我们就可以将我们的所有权限配置放置在config.php同级的user.php文件中,user.php文件配置如下:
<?php /** * 用户权限配置文件 */ return array( // 是否需要认证 'user_auth_on' => true, // 认证类型 1 登录认证 2 实时认证 'user_auth_type' => 1, // 后台用户认证session标记 'user_auth_key' => 'wjauthid', // 默认认证网关 'user_auth_gateway' => '?m=admin&c=login&a=index', // rbac_db_dsn 数据库连接dsn // 角色表名称,c('db_prefix')表示前缀 'rbac_role_table' => c('db_prefix') . 'role', // 用户角色关联表名称 'rbac_user_table' => c('db_prefix') . 'role_user', // 权限表名称 'rbac_access_table' => c('db_prefix') . 'access', // 节点表名称 'rbac_node_table' => c('db_prefix') . 'node', // 默认验证数据表模型 'user_auth_model' => 'user', // 超级管理员的session标记 'admin_auth_key' => 'wjadministrator', // 默认需要认证模块 'require_auth_module' => '', // 默认需要认证操作 'require_auth_action' => '', // 默认无需认证模块 'not_auth_module' => 'public', // 默认无需认证操作 'not_auth_action' => '', // 是否开启游客授权访问 'guest_auth_on' => false, // 游客的用户id 'guest_auth_id' => 0, // 后台用户名的session标记 'back_login_name' => 'loginbackname', // 后台角色的session标记 'back_user_role' => 'bakcuserrole', // 后台角色id的session标记 'back_role_id' => 'backroleid', // 后台用户登录时间的session标记 'back_online_time' => 'backonlinetime', // 后台在线间隔时间,以分钟为单位 'online_interval' => 180, //退出登录的url 'logout_url' => '/test', );
三:关于权限操作的常用方法:
1:rbac::saveaccesslist($authid=null);
缓存权限列表,在这个方法可以传递空值的前提是:你在用户登录操作的时候要在 $_session[c('user_auth_key')] 中把用户的id保存下来,然后这里会将用户所对应的角色拥有的权限都保存在$_session['_access_list']中
2:rbac::checkaccess()
判断用户访问的模块和方法是否需要权限认证
3:rbac::accessdecision()
断用户是否有访问权限的,即检测当前项目模块操作 是否在$_session['_access_list']数组中,也就是说 在 $_session['_access_list'] 数组中$_session'_access_list''当前控制器'是否存在。如果存在表示有权限 否则返回flase
4:rbac::checklogin();
判断用户是否登录,如果未登录则跳转到指定路径
5:rbac::getaccesslist($authid)
通过查询数据库 返回权限列表 $_session['_access_list']的值
6:rbac::authenticate($map, $model='')
传入查询用户的条件和用户表的model 返回数组包含用户的信息,如果不传model值的话使用配置项中的user_auth_model
四:权限管理简单实现实例:
1:登录:
//获取传递的用户名和密码 $username = i('post.username'); $password = i('post.password'); //生成认证条件 $map = array(); $map['username'] = $username; $map['status'] = array('eq', 1); //判断是否存在此用户 $authinfo = rbac::authenticate($map); if (!$authinfo) { $this->error('账号不存在'); } if ($authinfo['password'] != md5($password)) { $this->error('密码错误'); } $user_id = $authinfo['user_id']; $role_user = new model(); $role = $role_user->table(c("rbac_user_table"))->alias("user")->where("user_id=" . $user_id)->join(c("rbac_role_table") . " as role on role.id=user.role_id")->field("id,name")->find(); if (empty($role)) { $this->error('此用户无对应的角色,无法登录'); } //后台角色id的session标记 session(c('back_role_id'), $role['id']); //后台角色的session标记 session(c('back_user_role'), $role['name']); //后台用户认证session标记 session(c('user_auth_key'), $authinfo['user_id']); //后台用户名的session标记 session(c('back_login_name'), $authinfo['username']); //后台用户登录时间的session标记 session(c('back_online_time'), time()); //判断用户角色是否为超级管理员 if ($role['id'] == '1') { //超级管理员将超级管理员的session标记设置为true session(c('admin_auth_key'), true); } // 缓存访问权限 rbac::saveaccesslist(); $this->success('登录成功', u('index/index'));
2:登录成功后的权限校验:
//验证是否登录 rbac::checklogin(); // 用户权限检查 if (rbac::checkaccess() && !rbac::accessdecision()) { // 没有权限 清除登录session 并抛出错误 if (c('rbac_error_page')) { // 定义权限错误页面 redirect(c('rbac_error_page')); } else { if (c('guest_auth_on')) { //开启游客访问 } // 提示错误信息 $this->error(l('_valid_access_')); } } //自动退出功能,判断后台用户登录时间的session标记是否超时 if (session(c('back_online_time')) + c('online_interval') * 60 < time()) { if (session('?' . c('user_auth_key'))) { session('[destroy]'); if (isset($_cookie[session_name()])) { setcookie(session_name(), '', time() - 3600, '/'); } session_destroy(); } $this->error('超时请重新登录', u('login/index')); } else { session(c('back_online_time'), time()); }
根据如上就可以实现用户角色的权限管理
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。