thinkPHP3.2使用RBAC实现权限管理的实现

2022-10-16,,,

在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());
}

根据如上就可以实现用户角色的权限管理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

《thinkPHP3.2使用RBAC实现权限管理的实现.doc》

下载本文的Word格式文档,以方便收藏与打印。