RBAC权限模型建表及SQL语句编写

Posted wsfj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RBAC权限模型建表及SQL语句编写相关的知识,希望对你有一定的参考价值。

RBAC权限模型

RBAC权限模型(Role-Based Access Control)即:基于角色的权限控制。这是目前最常被开发者使用也是相对易用、通用权限模型。

建表及SQL语句编写

准备工作

创建数据库SQL表

CREATE DATABASE `sg_security` ;
 
USE `sg_security`;
 

 
DROP TABLE IF EXISTS `sys_menu`;
 
CREATE TABLE `sys_menu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `menu_name` varchar(64) NOT NULL DEFAULT \'NULL\' COMMENT \'菜单名\',
  `path` varchar(200) DEFAULT NULL COMMENT \'路由地址\',
  `component` varchar(255) DEFAULT NULL COMMENT \'组件路径\',
  `visible` char(1) DEFAULT \'0\' COMMENT \'菜单状态(0显示 1隐藏)\',
  `status` char(1) DEFAULT \'0\' COMMENT \'菜单状态(0正常 1停用)\',
  `perms` varchar(100) DEFAULT NULL COMMENT \'权限标识\',
  `icon` varchar(100) DEFAULT \'#\' COMMENT \'菜单图标\',
  `create_by` bigint(20) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_by` bigint(20) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `del_flag` int(11) DEFAULT \'0\' COMMENT \'是否删除(0未删除 1已删除)\',
  `remark` varchar(500) DEFAULT NULL COMMENT \'备注\',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT=\'菜单表\';
 

 
DROP TABLE IF EXISTS `sys_role`;
 
CREATE TABLE `sys_role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(128) DEFAULT NULL,
  `role_key` varchar(100) DEFAULT NULL COMMENT \'角色权限字符串\',
  `status` char(1) DEFAULT \'0\' COMMENT \'角色状态(0正常 1停用)\',
  `del_flag` int(1) DEFAULT \'0\' COMMENT \'del_flag\',
  `create_by` bigint(200) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_by` bigint(200) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `remark` varchar(500) DEFAULT NULL COMMENT \'备注\',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT=\'角色表\';
 

 
DROP TABLE IF EXISTS `sys_role_menu`;
 
CREATE TABLE `sys_role_menu` (
  `role_id` bigint(200) NOT NULL AUTO_INCREMENT COMMENT \'角色ID\',
  `menu_id` bigint(200) NOT NULL DEFAULT \'0\' COMMENT \'菜单id\',
  PRIMARY KEY (`role_id`,`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
 

 
DROP TABLE IF EXISTS `sys_user`;
 
CREATE TABLE `sys_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'主键\',
  `user_name` varchar(64) NOT NULL DEFAULT \'NULL\' COMMENT \'用户名\',
  `nick_name` varchar(64) NOT NULL DEFAULT \'NULL\' COMMENT \'昵称\',
  `password` varchar(64) NOT NULL DEFAULT \'NULL\' COMMENT \'密码\',
  `status` char(1) DEFAULT \'0\' COMMENT \'账号状态(0正常 1停用)\',
  `email` varchar(64) DEFAULT NULL COMMENT \'邮箱\',
  `phonenumber` varchar(32) DEFAULT NULL COMMENT \'手机号\',
  `sex` char(1) DEFAULT NULL COMMENT \'用户性别(0男,1女,2未知)\',
  `avatar` varchar(128) DEFAULT NULL COMMENT \'头像\',
  `user_type` char(1) NOT NULL DEFAULT \'1\' COMMENT \'用户类型(0管理员,1普通用户)\',
  `create_by` bigint(20) DEFAULT NULL COMMENT \'创建人的用户id\',
  `create_time` datetime DEFAULT NULL COMMENT \'创建时间\',
  `update_by` bigint(20) DEFAULT NULL COMMENT \'更新人\',
  `update_time` datetime DEFAULT NULL COMMENT \'更新时间\',
  `del_flag` int(11) DEFAULT \'0\' COMMENT \'删除标志(0代表未删除,1代表已删除)\',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT=\'用户表\';
 

 
DROP TABLE IF EXISTS `sys_user_role`;
 
CREATE TABLE `sys_user_role` (
  `user_id` bigint(200) NOT NULL AUTO_INCREMENT COMMENT \'用户id\',
  `role_id` bigint(200) NOT NULL DEFAULT \'0\' COMMENT \'角色id\',
  PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

根据userid查询 perms 对应的role和menu都必须是正常状态的

SELECT 
    DISTINCT m.`perms`
FROM
    sys_user_role ur
    LEFT JOIN `sys_role` r ON ur.`role_id` = r.`id`
    LEFT JOIN `sys_role_menu` rm ON ur.`role_id` = rm.`role_id`
    LEFT JOIN `sys_menu` m ON m.`id` = rm.`menu_id`
WHERE
    user_id = 2
    AND r.`status` = 0
    AND m.`status` = 0

菜单表(Menu)实体类

package com.sangeng.domain;
 
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.io.Serializable;
import java.util.Date;
 
/**
 * 菜单表(Menu)实体类
 *
 * @author makejava
 * @since 2021-11-24 15:30:08
 */
@TableName(value="sys_menu")
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Menu implements Serializable 
    private static final long serialVersionUID = -54979041104113736L;
    
        @TableId
    private Long id;
    /**
    * 菜单名
    */
    private String menuName;
    /**
    * 路由地址
    */
    private String path;
    /**
    * 组件路径
    */
    private String component;
    /**
    * 菜单状态(0显示 1隐藏)
    */
    private String visible;
    /**
    * 菜单状态(0正常 1停用)
    */
    private String status;
    /**
    * 权限标识
    */
    private String perms;
    /**
    * 菜单图标
    */
    private String icon;
    
    private Long createBy;
    
    private Date createTime;
    
    private Long updateBy;
    
    private Date updateTime;
    /**
    * 是否删除(0未删除 1已删除)
    */
    private Integer delFlag;
    /**
    * 备注
    */
    private String remark;

RBAC 基于角色的访问控制演示

RBAC


rbac:Role Based Access Controll,基于角色的访问控制。

今天理一理RBAC,话不多说,直接切入主题

 

功能需求:

  1. 权限管理(无限极)
  2. 角色管理(可以分配权限)
  3. 管理员管理(管理员属于哪些角色)
  4. 后台左侧显示当前登录用户所拥有的权限
  5. 超级管理员拥有所有权限

实现

建表(我们需要三个表,管理员表、角色表、权限表,tip:也可用其它建表方式)

管理员表

权限表

角色表

我制作完的三张表的CRUD,后台首页效果展示(具体的增删改查就不列步骤了):

管理员表

权限表

角色表

 

 功能一实现-无限极权限分类


 

  在这里实现无限极分类不是通过递归,而是通过建表时候多加的一个字段 auth_path

 

不懂的看我另一篇博文有写不使用递归实现无限极,这里就不多说了

功能二实现-角色管理分配权限


 

页面实现

视图显示没有什么可说的,有需要源码的、有问题的留言,收集表单信息(tp代码示意)

然后我们讲得到的数组转换成字符串,通过字符串查询所有权限信息

返回数组

接下来拼接字段role_auth_ac,通过get过来的角色id更新数据库

 

 1     public function saveAuth($arr,$role_id){
 2         $str = implode(\',\',$arr);
 3         $str = rtrim($str);
 4         
 5         $auth_info = D(\'Auth\')->select($str);
 6         $s = \'\';//用于拼接 role_auth_ac 字段
 7         foreach($auth_info as $v){
 8             if(!empty($v[\'auth_c\']) && !empty($v[\'auth_a\'])){
 9                  $s .= $v[\'auth_c\'] .\'-\'. $v[\'auth_a\'].\',\';               
10             }
11         }
12         $s = rtrim($s,\',\');
13         $sql = "update jy_role set role_auth_ids = \'$str\',role_auth_ac = \'$s\' where role_id = $role_id";
14         return $this->execute($sql);
15     }

 

功能三实现-管理员属于的角色


 

 

 

功能四/五 实现-登录左侧显示所拥有权限


比如我现在用另一个账号登录,(只显示他有的权限) 

基本思想就是,首先登录后将管理员的角色id获得,不同的角色id根据数据库里的数据显示不同权限菜单,如下,我的jy_test只有两个权限

 

视图中显示如下

 

tp代码示意

        $admin_id = session("admin_info[\'admin_id\']");//管理员id
     
        $admin_info = D(\'Admin\')->find($admin_id);//管理员信息
        $role_id = $admin_info[\'role_id\'];//管理员角色id
        
        //角色信息
        $role_info = M(\'Role\')->find($role_id);
        //角色拥有的权限字符串
        $auth_ids = $role_info[\'role_auth_ids\'];
        
        if($role_id === 0){
            //超级管理员获取所有权限菜单
           $auth_infoA = M(\'Auth\')->where("auth_level = 0")->select();  //顶级权限
           $auth_infoB = M(\'Auth\')->where("auth_level = 1")->select();  //次顶级权限 
        }else{
            $auth_infoA = M(\'Auth\')->where("auth_level = 0 and auth_id in ($auth_ids)")->select();  //顶级权限
            $auth_infoB = M(\'Auth\')->where("auth_level = 1 and auth_id in ($auth_ids)")->select();  //次顶级权限

后记:只是大致笼统粗糙的说了下流程,有需要源码和有问题的可以私我!

 

 

 

 

以上是关于RBAC权限模型建表及SQL语句编写的主要内容,如果未能解决你的问题,请参考以下文章

权限管理(RBAC模型) 一条SQL查询出菜单

用sql语句怎么查一个表的信息

用sql语句怎么查一个表的信息

怎样用oracle查建表语句

基于RBAC模型的通用权限管理,可以直接使用

RBAC 基于角色的访问控制演示