权限管理的五张表
前言:
一个成熟的系统系统是离不开权限管理的,说权限管理就必须要说下权限管理经典的五张表了,无论是自定义的权限管理框架,还是流行的Shiro、SpringSecurity等权限管理框架都是离不开这五张表的,哪五张表呢,一起看下。
一.五张表
五张表分别是:用户表、角色表、权限表、用户角色表、角色权限表。
本文只列举核心字段,扩展的业务字段是可以随便加的,比如创建时间、数据状态,这些扩展字段这里不做详细列举
1.用户表 user
一个系统少则几十个,多则成千上万个用户。我们会为每一个用户存储用户信息,用以该用户在登录时进行验证是否是合法的用户。该表的唯一作用也就是存储合法的用户信息。
/*
Navicat Premium Data Transfer
Source Server : 虚拟机
Source Server Type : MySQL
Source Server Version : 50731
Source Host : 192.168.150.100:3306
Source Schema : shiro
Target Server Type : MySQL
Target Server Version : 50731
File Encoding : 65001
Date: 29/04/2022 10:49:07
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for shiro_user
-- ----------------------------
DROP TABLE IF EXISTS `shiro_user`;
CREATE TABLE `shiro_user` (
`oid` int(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
`salt` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of shiro_user
-- ----------------------------
INSERT INTO `shiro_user` VALUES (1, '张三', '104a001d809335b079cb21abe8a41dc8', '*Z*0mtNG1y');
INSERT INTO `shiro_user` VALUES (10, '秦始皇', '104a001d809335b079cb21abe8a41dc8', '*Z*0mtNG1y');
INSERT INTO `shiro_user` VALUES (11, 'luban', '4b978f418f597f2f95da1dd42faebf64', 'Dy$;XsWhG7');
SET FOREIGN_KEY_CHECKS = 1;
2.角色表 role
一个系统拥有很多的用户,所以在实现权限管理时,我们不可能去根据用户进行实现权限控制,但是不同的用户又拥有很多的共性,因此我们根据用户的共性将用户划分为几种不同的角色,比如游客、普通会员、操作员、管理员、超级管理员等。这样我们只需要为每个用户指定一个角色,就可以轻松的根据角色进行判定当前用户是什么级别的用户了。
/*
Navicat Premium Data Transfer
Source Server : 虚拟机
Source Server Type : MySQL
Source Server Version : 50731
Source Host : 192.168.150.100:3306
Source Schema : shiro
Target Server Type : MySQL
Target Server Version : 50731
File Encoding : 65001
Date: 29/04/2022 10:48:48
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for shiro_role
-- ----------------------------
DROP TABLE IF EXISTS `shiro_role`;
CREATE TABLE `shiro_role` (
`oid` int(20) NOT NULL,
`role` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of shiro_role
-- ----------------------------
INSERT INTO `shiro_role` VALUES (1, 'admin');
INSERT INTO `shiro_role` VALUES (2, 'user');
SET FOREIGN_KEY_CHECKS = 1;
3.权限表也叫资源表 permission
一个系统中,我们可以将前端的页面看成一个资源,可以将前端的按钮看成资源,我们也可以将后端的接口看成资源。我们可以将一切需要控制访问权限的资源都配置在权限表中。大部分场景下我们的权限表都是存储资源描述符字符串比如:user:supplier:view。这既是一个资源描述符,如果一个资源的描述符是这个,那么用户只有拥有user:supplier:view,或者user:supplier:*(这里只关注操作位,其他两位为*也是可以的)。这两种资源描述符才可以正常访问到目标资源。
/*
Navicat Premium Data Transfer
Source Server : 虚拟机
Source Server Type : MySQL
Source Server Version : 50731
Source Host : 192.168.150.100:3306
Source Schema : shiro
Target Server Type : MySQL
Target Server Version : 50731
File Encoding : 65001
Date: 29/04/2022 10:48:39
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for shiro_permission
-- ----------------------------
DROP TABLE IF EXISTS `shiro_permission`;
CREATE TABLE `shiro_permission` (
`oid` int(20) NOT NULL,
`permission` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of shiro_permission
-- ----------------------------
INSERT INTO `shiro_permission` VALUES (1, 'admin:context:view');
INSERT INTO `shiro_permission` VALUES (2, 'admin:context:update');
SET FOREIGN_KEY_CHECKS = 1;
4.用户角色表 user_role_relation
用户怎么与角色表建立连接呢,自然就是通过用户角色表来建立这两张表的关系了。那么不可以使用外键来关联吗?当然是可以的,只不过本着解耦合的理念,对表的职责进行单一化处理。大部分场景都是不使用外键而是使用关系表来建立用户与角色的连接。
/*
Navicat Premium Data Transfer
Source Server : 虚拟机
Source Server Type : MySQL
Source Server Version : 50731
Source Host : 192.168.150.100:3306
Source Schema : shiro
Target Server Type : MySQL
Target Server Version : 50731
File Encoding : 65001
Date: 29/04/2022 10:49:14
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for shiro_user_role_relation
-- ----------------------------
DROP TABLE IF EXISTS `shiro_user_role_relation`;
CREATE TABLE `shiro_user_role_relation` (
`oid` int(20) NOT NULL,
`shiro_user_oid` int(20) NULL DEFAULT NULL,
`shiro_role_oid` int(20) NULL DEFAULT NULL,
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of shiro_user_role_relation
-- ----------------------------
INSERT INTO `shiro_user_role_relation` VALUES (1, 10, 1);
INSERT INTO `shiro_user_role_relation` VALUES (2, 10, 2);
SET FOREIGN_KEY_CHECKS = 1;
5.角色权限表 role_permission_relation
同理,该表就是为了建立角色与权限的连接。实现了用户到角色,角色到权限的转换,这样我们就可以为每个用户都分配到不同的权限了。
/*
Navicat Premium Data Transfer
Source Server : 虚拟机
Source Server Type : MySQL
Source Server Version : 50731
Source Host : 192.168.150.100:3306
Source Schema : shiro
Target Server Type : MySQL
Target Server Version : 50731
File Encoding : 65001
Date: 29/04/2022 10:48:59
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for shiro_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `shiro_role_permission`;
CREATE TABLE `shiro_role_permission` (
`oid` int(20) NOT NULL,
`shiro_role_oid` int(20) NULL DEFAULT NULL,
`shiro_permission_oid` int(20) NULL DEFAULT NULL,
PRIMARY KEY (`oid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of shiro_role_permission
-- ----------------------------
INSERT INTO `shiro_role_permission` VALUES (1, 1, 1);
SET FOREIGN_KEY_CHECKS = 1;
二.总结
1.权限管理的核心是角色表 role
角色的作用就是一个桥梁,他连接了用户与权限,自己却不会做什么事情,在基于资源描述符实现的权限管理系统里(当然也有基于角色实现的),我们是用不到角色的。角色就像是一个什么都不做的中间商,只是将用户与权限进行关联,告诉系统这个角色拥有哪些权限,真正判断时还是判断的权限表的内容。
2.三张表也可以实现权限管理
其实我们只需要用户表、角色表、权限表,这三张表也可以实现权限管理。三者的关系的建立,我们就通过在用户表增加外键,在角色表增加外键就可以实现,但是一般我们为了解耦合,是不会这么做的,这么做也降低了可读性,一般建议还是按照五张表的理念去实现。