/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 100412
Source Host : localhost:22066
Source Schema : base_db
Target Server Type : MySQL
Target Server Version : 100412
File Encoding : 65001
Date: 15/03/2020 11:28:38
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_base_person_role
-- ----------------------------
DROP TABLE IF EXISTS `t_base_person_role`;
CREATE TABLE `t_base_person_role` (
`person_role_id` int(11) NOT NULL COMMENT '主键ID',
`identity_id` int(11) NOT NULL COMMENT '身份ID',
`person_id` int(11) NOT NULL COMMENT '人员ID',
`role_id` int(11) NOT NULL COMMENT '角色ID',
`business_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '哪个省?哪个市?哪个县?哪个单位?哪个子单位?',
`update_ts` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间戳',
PRIMARY KEY (`person_role_id`) USING BTREE,
UNIQUE INDEX `identity_id`(`identity_id`, `person_id`, `role_id`, `business_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_base_person_role
-- ----------------------------
-- ----------------------------
-- Table structure for t_base_resource
-- ----------------------------
DROP TABLE IF EXISTS `t_base_resource`;
CREATE TABLE `t_base_resource` (
`resource_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`resource_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源名称',
`resource_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源代码',
`resource_sql` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '查找对应单位的SQL',
`update_ts` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后更新时间戳',
PRIMARY KEY (`resource_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_base_resource
-- ----------------------------
INSERT INTO `t_base_resource` VALUES (1, '单位', 'bureau_id', 'select ? as bureau_id', '2020-03-15 11:27:48');
INSERT INTO `t_base_resource` VALUES (2, '学校', 'school_id', 'select ? as bureau_id', '2020-03-15 11:28:08');
INSERT INTO `t_base_resource` VALUES (3, '班级', 'class_id', 'select bureau_id from t_base_class where class_id=?', '2020-03-15 11:14:39');
INSERT INTO `t_base_resource` VALUES (4, '部门', 'org_id', 'select bureau_id from t_base_organization where org_id=?', '2020-03-15 11:19:47');
INSERT INTO `t_base_resource` VALUES (5, '教职工', 'teacher_id', 'select bureau_id from t_base_teacher where teacher_id=?', '2020-03-15 11:23:02');
INSERT INTO `t_base_resource` VALUES (6, '学生', 'student_id', 'select bureau_id from t_base_student where student_id=?', '2020-03-15 11:20:34');
INSERT INTO `t_base_resource` VALUES (7, '家长', 'parent_id', 'select bureau_id from t_base_parent where parent_id=?', '2020-03-15 11:20:53');
-- ----------------------------
-- Table structure for t_base_role
-- ----------------------------
DROP TABLE IF EXISTS `t_base_role`;
CREATE TABLE `t_base_role` (
`role_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`role_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
`distribute_able` int(255) NOT NULL DEFAULT 1 COMMENT '是否可以分配给真实的人员',
`update_ts` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间戳',
PRIMARY KEY (`role_id`) USING BTREE,
INDEX `distribute_able`(`distribute_able`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '(1)此角色表是基础数据内置的角色表,不是为共享给其它系统的公用概念,与分管工作有本质的区别。
(2)有指定角色的人员,不管是真实的人员,还是系统虚拟的管理人员,都需要在指定角色时配置数据范围,即哪个市,哪个校,哪个区,哪个单位
(3)系统管理员是不能二次分配给真实人员的。
(4)除系统管理员外,其它管理员角色是不可分配给真实人员的。' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_base_role
-- ----------------------------
INSERT INTO `t_base_role` VALUES (1, '系统管理员', 0, '2020-03-15 10:11:43');
INSERT INTO `t_base_role` VALUES (2, '省管理员', 1, '2020-03-15 10:11:43');
INSERT INTO `t_base_role` VALUES (3, '市管理员', 1, '2020-03-15 10:11:43');
INSERT INTO `t_base_role` VALUES (4, '县区管理员', 1, '2020-03-15 10:11:43');
INSERT INTO `t_base_role` VALUES (5, '单位管理员', 1, '2020-03-15 10:11:43');
INSERT INTO `t_base_role` VALUES (6, '分校(教学点)管理员', 1, '2020-03-15 10:11:43');
-- ----------------------------
-- Table structure for t_sys_identity
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_identity`;
CREATE TABLE `t_sys_identity` (
`identity_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '身份ID',
`identity_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '身份名称',
`exposed` int(255) NOT NULL DEFAULT 1 COMMENT '其它系统是否可见',
`update_ts` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间戳',
PRIMARY KEY (`identity_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_identity
-- ----------------------------
INSERT INTO `t_sys_identity` VALUES (1, '系统管理员', 0, '2020-03-15 10:13:10');
INSERT INTO `t_sys_identity` VALUES (2, '教职工', 1, '2020-03-15 10:13:10');
INSERT INTO `t_sys_identity` VALUES (3, '学生', 1, '2020-03-15 10:13:10');
INSERT INTO `t_sys_identity` VALUES (4, '家长', 1, '2020-03-15 10:13:10');
-- ----------------------------
-- Table structure for t_sys_loginperson
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_loginperson`;
CREATE TABLE `t_sys_loginperson` (
`login_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`login_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '登录名',
`person_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
`pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '盐',
`identity_id` int(11) NOT NULL COMMENT '身份ID',
`person_id` int(11) NOT NULL COMMENT '人员ID',
`update_ts` datetime(0) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间戳',
PRIMARY KEY (`login_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_sys_loginperson
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
2、利用swagger的注释进行角色访问权限控制
// PingExample godoc
// @Summary 获取一条数据记录的示例
// @Description 获取一条数据记录的示例
// @Tags 获取一条数据记录的示例
// @Accept json
// @Param id query int true "单条记录的id"
// @Produce json
// @Success 200 {string} string "pong"
// @Router /shortcutkey/SelectSingle [get]
// @X-Role-Resource {"role_id":[1,2,3,4,5],"resource_id":1}
最后这一句是有用的,描述了哪些角色可以使用这个接口,本接口相关的是哪类资源。
3、每次构建前
swag init
4、初始化拦截器检查列表
//读取doc目录下的swagger.json
f, err := os.Open("./docs/swagger.json")
if err != nil {
fmt.Println("读取swagger.json失败!")
return
}
content, _ := ioutil.ReadAll(f)
var inter interface{}
err = json.Unmarshal(content, &inter)
if err != nil {
fmt.Println("ERROR: ", err.Error())
return
}
var xRoleResource map[string]interface{}
m := inter.(map[string]interface{})
n := m["paths"].(map[string]interface{})
for k,v := range n {
t:=v.(map[string]interface{})
if t["get"]!=nil{
d:=t["get"].(map[string]interface{})
xRoleResource =d["x-role-resource"].(map[string]interface{})
}
if t["post"]!=nil{
p:=t["post"].(map[string]interface{})
xRoleResource =p["x-role-resource"].(map[string]interface{})
}
fmt.Println("接口地址:"+k)
fmt.Println("使用的资源ID:"+fmt.Sprintf("%d", int(xRoleResource["resource_id"].(float64))))
t1:=xRoleResource["role_id"].([]interface{})
for i := 0; i < len(t1); i++ {
fmt.Print(int(t1[i].(float64)), " ")
}
}
5、在拦截器中进行拦截检查
1、根据cookie中的加密串,解密还原为identity_id和person_id.
2、根据identity_id+person_id查询t_base_person_role,获取到role_id,business_id(可能是省市县,单位,子单位),考虑性能,可以读取一次后保存到缓存中,有TTL值,比如10分钟。
3、根据swagger的解析json,可以知道当前拦截的接口是哪个,需要拦截的resource_id是什么,限定的role_id有哪些。
4、根据统一获取的bureau_id,通过一个通用接口,获取单位的省市县,单位,子单位等一系列值,考虑到性能,可以上基础数据开发人员提供,在维护更新单位时一并删除缓存即可。
5、两组数据进行交叉对比,存在交集表示可以操作,否则是没有权限操作此接口,挡回。
6、总结
(1)此设计对整体系统要有控制权,每一个环节必须按要求开发,比如统一的bureau_id参数。
(2)此设计无通用性,只能是一种思路。
(3)性能上可以通过缓存等方式进行减压,并发也没有关系。
(4) 每个系统,需要有独立的mysql用户帐号,不能都统一用root,基础数据也不能使用root,因为一旦被暴库,可能全面有被删除数据的风险,使用权限低的mysql帐号,可以限定操作权只在自己的数据库内,不会损坏其它系统的数据,这个确实非常重要。