在开发后台管理系统的时候,例如OA系统,绩效系统,crm客户关系管理系统,都会存在用户权限划分的问题。该文章描述了角色的定义,以及权限的划分等含义。如下图所示:

  1. useruser_basicinfo:记录用户资料。
  2. role:角色表,记录公司各种角色,比如:管理员,销售,销售主管,开发,开发经理等
  3. permission:菜单表,记录系统的菜单栏目和页面上的按钮(例如:绩效管理,会议管理,新增绩效,预约会议),包括url和code等信息。
  4. role_permission:角色权限表,记录某个角色有多少个菜单。一个角色对应多个菜单,菜单不可重复。
  5. user_role:用户角色表,用户可拥有多个角色。

一.建表脚本

CREATE TABLE `permission` (`ID` int(11) NOT NULL AUTO_INCREMENT,`PID` int(11) DEFAULT NULL COMMENT '父节点名称',`NAME` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '名称',`TYPE` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '类型:菜单or功能',`SORT` int(11) DEFAULT NULL COMMENT '排序',`URL` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '菜单URL',`PERM_CODE` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '菜单编码',`ICON` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '图标',`STATE` varchar(10) COLLATE utf8_bin DEFAULT NULL,`DESCRIPTION` varchar(200) COLLATE utf8_bin DEFAULT NULL,`CATEGORY_ID` bigint(20) DEFAULT NULL COMMENT '导航ID',`ICON_URL` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '图标的URL',`IS_VALID` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0 有效  1 无效',`DOMAIN_ID` int(11) DEFAULT NULL COMMENT '来源系统ID',PRIMARY KEY (`ID`),KEY `idx_pid` (`PID`)
) ENGINE=InnoDB AUTO_INCREMENT=177 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜单';
CREATE TABLE `role` (`ID` int(11) NOT NULL AUTO_INCREMENT,`NAME` varchar(20) COLLATE utf8_bin NOT NULL COMMENT '角色名称',`ROLE_CODE` varchar(20) COLLATE utf8_bin NOT NULL COMMENT '角色编码',`DESCRIPTION` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '角色描述',`SORT` smallint(6) DEFAULT NULL COMMENT '排序',`DEL_FLAG` varchar(255) COLLATE utf8_bin DEFAULT NULL,PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色表';
CREATE TABLE `role_permission` (`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',`ROLE_ID` int(11) DEFAULT NULL COMMENT '角色id',`PERMISSION_ID` int(11) DEFAULT NULL COMMENT '菜单ID',PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=614 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='角色权限表';CREATE TABLE `user_role` (
  `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`USER_ID` int(11) NOT NULL COMMENT '用户ID',`ROLE_ID` int(11) NOT NULL COMMENT '角色ID',PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=327 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户角色表';
用户表结构就不贴了。

二.url拦截

            permission表中的菜单和按钮如何控制?

方案一:当然做得简单点,登录时获取用户权限信息,有权限则显示菜单和按钮标签,无权限则隐藏。(不推荐)

方案二:在方案一的基础上做个拦截器,每次访问url的时候,判断该用户是否有该权限。

拦截器:

package com.dfws.manage.utils;import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.StringTokenizer;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.http.entity.ContentType;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.alibaba.druid.util.StringUtils;
import com.dfws.manage.base.ApiResult;
import com.dfws.manage.customer.dto.Login;
import com.dfws.manage.shiro.redis.conf.CasTicketCache;
import com.dfws.manage.user.domain.DfwsSysUserAccount;
import com.dfws.manage.user.service.DfwsSysUserAccountService;
import com.tianyu.jty.system.share.SharedUser;/*** 登陆拦截器*/public class AuthorizeInterceptor extends HandlerInterceptorAdapter {private static final Logger logger = Logger.getLogger(AuthorizeInterceptor.class);private final String loginUrl = "/notLogin";//未登录接口地址public static Collection<String> ANON_URLS = new ArrayList<String>();public static String DEFAULT_SEPARATOR = ",";@Value(value = "${cas.logout.url}")private String logoutUrl;@Autowired@Qualifier(value = "casTicketCache")private CasTicketCache casTicketCache;public static void setAnonUrls(String anonUrls) {StringTokenizer tokenizer = new StringTokenizer(anonUrls, DEFAULT_SEPARATOR);while(tokenizer.hasMoreElements()) {String token = tokenizer.nextToken();ANON_URLS.add(token);}ANON_URLS = Collections.unmodifiableCollection(ANON_URLS);}@Autowiredprivate DfwsSysUserAccountService userAccountService;@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {super.postHandle(request, response, handler, modelAndView);}/*** 前置处理*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String uri = request.getRequestURI();String contextPath = request.getContextPath();String uriWithoutContx = uri.substring(contextPath.length());if (ANON_URLS.contains(uriWithoutContx)) {return true;}System.out.println("请求接口:" + uriWithoutContx);System.err.println(request.getParameter("loginName"));System.err.println(request.getParameter("token"));String loginName = request.getParameter("loginName");String token = request.getParameter("token");boolean reLogin = false;if(uriWithoutContx.contains("dict") || uriWithoutContx.equals("crm")|| uriWithoutContx.equals("excel")){return true;}if (!StringUtils.isEmpty(loginName) && !StringUtils.isEmpty(token)) {SharedUser user = casTicketCache.get(token);if (user == null ) {reLogin = true;}} else {reLogin = true;}// 需要做重新登陆if (reLogin) {// System.out.println(request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+loginUrl+"/" );// System.out.println(request.getContextPath() + loginUrl);// response.sendRedirect(request.getContextPath() + loginUrl);response.sendRedirect(logoutUrl);return false;} else { // 不需要做重新登陆return true;}// return super.preHandle(request, response, handler);}@Overridepublic void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {super.afterConcurrentHandlingStarted(request, response, handler);}/*** 结束处理*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {super.afterCompletion(request, response, handler, ex);}/*** 获取http的所有请求参数*/private String getAllParamFromHttpReq(HttpServletRequest request) {Enumeration paramNames = request.getParameterNames();StringBuffer sb = new StringBuffer();while (paramNames.hasMoreElements()) {String paramName = (String) paramNames.nextElement();String[] paramValues = request.getParameterValues(paramName);if (paramValues.length == 1) {String paramValue = paramValues[0];if (paramValue.length() != 0) {sb.append("&").append(paramName).append("=").append(paramValue);}}}return sb.toString();}}
    <!-- 全局拦截器处理 --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**/*"/><mvc:exclude-mapping path="/css/**"/><mvc:exclude-mapping path="/**/*.css"/><mvc:exclude-mapping path="/js/**"/><mvc:exclude-mapping path="/**/*.js"/><mvc:exclude-mapping path="/img/**"/><mvc:exclude-mapping path="/fonts/**"/><mvc:exclude-mapping path="/backstage/**"/><mvc:exclude-mapping path="/preLogin/**"/><mvc:exclude-mapping path="/login/**"/><mvc:exclude-mapping path="/captcha/**"/><!-- 直接将bean配置到mvc:interceptors,将会应用到所有的url请求HandlerMapping,达到全局拦截器的目的。 --><bean class="com.dfws.manage.utils.AuthorizeInterceptor"/></mvc:interceptor></mvc:interceptors>

三:权限扩展(数据权限)

      上面仅仅实现了用户的基本菜单和按钮权限,然后一个大型公司的项目,数据比较敏感,会控制菜单的数据展示范围。数据权限的控制根据公司业务需求定义。下面提两个参考方案。
  1. 根据部门划分数据权限,新增数据权限角色,将部门挂载这个角色中,然后给这个角色添加人员。有该角色的人,则可以看到该角色下的所有部门。比如:客户管理栏目,本来是可以看到公司所有客户信息,加了数据权限后,你只能看到你所在角色的部门和下级部门的数据的,如果你的角色拥有的全公司的部门,则你能看到全公司的数据。在写sql的时候,用where in查找即可,in里面查询的是员工id。
  2. 数据权限直接分配到个人,数据权限与人绑定关系,数据权限范围:全公司,多个部门和个人。比如:小李,需要看到小张的数据,则把小张的数据权限分配给小李下即可。

注:方案一相对来说较简单,易维护。方案二数据权限比较复杂,灵活方便,不好维护。

后台管理系统权限设计相关推荐

  1. python开发企业管理平台_我的第一个python web开发框架(34)——后台管理系统权限设计...

    框架底层和接口终于改造完成了,小白再次找到老菜. 小白:老大,上次你对后台权限系统简单的讲了一下,我一点头绪都没有,现在有空完整的说一说吗? 老菜:说到权限系统,要讲明白真不容易,权限系统并不是越复杂 ...

  2. VUE后台管理系统权限管理

    VUE后台管理系统权限管理(面试路由守卫) 1.背景 后台管理系统中总会遇到权限分配的问题:这也是一道vue的很经典的面试问题 2.解决思路 权限管理无非前端或者后台解决 先说一下前端解决的思路:在设 ...

  3. P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态

    P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态 文章目录 P22-Vue3后台管理系统-权限管理之路由守卫判断⽤户登录状态 1.概述 2.mock接口返回token 2.1.mock ...

  4. SSM框架实现后台管理系统权限管理(用户、菜单、角色)

    文章目录 后台管理系统开发 一.数据库表结构设计 1.菜单表menu 2.用户表user 3.角色表role 4.角色权限表role_menu 5.用户角色表user_role 二.项目准备 1.创建 ...

  5. 06_04_SSM拉勾教育后台管理系统(权限模块\登录及动态菜单)

    拉勾教育后台管理系统(SSM)权限模块 权限概念介绍 权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做 认证: 验证用户名密码是否正确的过程 授权: 对用 ...

  6. 【完善】微信餐厅点单小程序+后台管理系统的设计与实现(python实现)

    前言 本文为完善上一篇文章餐厅点单小程序+后台管理管理系统的设计与实现,旨在帮助有需要的小伙伴,更好的入门学习python3 django+vue开发的前后端分离框架.话不多说,开始我们的学习吧- 项 ...

  7. 后台管理系统权限管理详解

    权限管理 简述权限管理: 你可以在后台通过一个 tree 控件或者其它展现形式给每一个页面动态配置权限,之后将这份路由表存储到后端.当用户登录后得到roles,前端根据roles去向后端请求可访问的路 ...

  8. 浅聊下后台管理系统权限控制的实现思路

    总览: 总的思路来讲实现权限控制分为页面的权限以及页面按钮的权限,页面权限可以简单理解为哪些页面这个用户可以看见,哪些页面用户不能看见,按钮权限同理,哪些按钮用户可以看见,哪些按钮用户看不见,为什么不 ...

  9. zsy后台管理系统-架构设计

    Zsy框架总体架构设计 1.Mysql数据库,存储所有表的数据. 2.Zsy-基础项目(Zsy-Model,Zsy-Dao,Zsy-Service,Zsy-Web),基于SSM框架.项目功能包含基本的 ...

  10. elm_flask 项目日志 -- flask后台管理系统开发设计

    后台管理项目日志 项目初始化阶段 仓库使用 注册码云平台 创建工程仓库 创建自己的开发分支 clone/push/pull的操作 新建开发分支 能够在远程分支进行pull和push 项目搭建 搭建项目 ...

最新文章

  1. 异常数据4种剔除方法_数据分析系列 22/32 | 9种常用的数据分析方法
  2. java lambda函数_Java SE 8新功能介绍:使用Lambda Expression进行函数式编程
  3. python训练模型太大怎么处理_趣味Python之如何降低过拟合风险
  4. 卡耐基梅隆大学CMU Brandon Amos博士论文《可微优化机器学习建模》
  5. 虎扑APP遭全网下架 原因未知
  6. linux 自定义安装软件,在/ usr中跟踪Linux上自定义软件安装的最佳实践?
  7. 傅立叶变换系列(四)离散傅立叶变换
  8. C语言经典弱智问题解法整理
  9. linux中设备配额 磁盘加密
  10. left join on 左边为主
  11. Handheld Group推出Algiz平板,内置RFID读取器
  12. Asp.net常用的51个代码(非常实用)
  13. 用友U815.0UFO报表知识点分享
  14. SQLService2012下载和安装
  15. 基于二维激光雷达的三维激光扫描系统的设计与实现
  16. 什么是静电?什么是ESD?ESD分为几种形式?有哪些测试标准?
  17. ERP系统实施之入门
  18. php 依赖安装顺序6,构建PHP框架:第6部分-依赖倒置,控制倒置,哦,天哪!
  19. Python ------ return返回值等
  20. 典型的多层神经网络模型,神经网络多传感器融合

热门文章

  1. 车型数据导入excel
  2. 车型代号对照表_车型与VIN代号对照表
  3. freeotp使用教程_PPT模板怎么用
  4. 笔记 c语言99乘法表
  5. 会员积分营销系统,现代营销利器
  6. 强联通分量:Tarjan缩点
  7. excel多元线性拟合_急!!!用excel做的多元线性回归分析~|excle做三元回归
  8. 无法打开网上邻居计算机,win7网上邻居在哪 无法访问怎么办【图文】
  9. 安徽大学本科毕业论文中英文题目修改指南
  10. 001如何将灰度视频处理为伪彩色