欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-29 13:23:53
在thinkphp3.2中自己集成了rbac来实现权限管理,rbac实现类在项目中地址为:thinkphp/librar/org/util/rbac.class.php,其...

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

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

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