不管是开发手机APP,网站还是小程序等项目,基本上都需要一个后台管理系统的支撑。而每个后台管理系统都有一个通用的功能就是用户权限管理。最近基于Antd pro+React.js做了一个后台管理系统。


一、概要

权限管理是一个几乎所有网站的都会涉及的一个重要组成部分,主要目的是对整个系统进行权限的控制,包括API权限和功能权限。避免因权限控制缺失或操作不当引发的系统风险问题,如操作错误,数据泄露等问题。

就目前来说使用最广泛的是一个账号对应多个角色,每个角色对应相应的权限集(RBAC模型)这种模型基本可以应对所有的问题,且通过角色可以实现灵活且多样的的权限操作需求。

权限管理中涉及到三个重要的名词:账号、角色、权限。

  • 账号:任何用户想要进入系统需要分配一个账号,而这个账号就是一把钥匙。我们通过控制账号所具备的权限,进而控制这个用户的授权范围。
  • 角色:角色管理是确定角色具备哪些权限的一个过程,他是一个集合的概念,是众多最小权限颗粒的组成。我们通过把权限给这个角色,再把角色给账号,从而实现账号的权限,因此它承担了一个桥梁的作用。
  • 权限:权限包括页面权限,操作权限,数据权限。页面权限控制你可以看到哪个页面,看不到哪个页面;操作权限则控制你可以在页面上操作哪些按钮;数据权限则是控制你可以看到哪些数据。

二、思考

了解过很多网上给出的权限管理方案,绝大部分解决方案都是事先定义好角色和各个页面权限的对应关系,这样做有一个缺点就是无法灵活配置。比如要调整一个角色的权限,那系统需要从代码层面做相应的修改。所以在想有没有一种解决方案可以把权限的颗粒度划分的更细,通过洁面实现角色和权限动态配置。

带着这些疑问整理了自己对权限管理的理解和解决方案,本人非专业WEB端开发,只是提出个人见解,有不对的地方希望大家指正。上面也说了权限主要分为页面权限、操作权限和数据权限,我想从这三个方面细化并做成可自由配置。

页面权限控制:页面权限主要通过菜单配置和页面跳转操作来控制。一般进入后台管理系统会呈现出主菜单,我们可以在角色管理中为每一个角色配置不同的菜单以及前端页面的功能标识。用户使用账号登录时,后台通过判断该账号的角色,返回对应的菜单和功能标识,这样就可以控制用户的一级页面的权限和跳转到二级页面的入口,从而实现控制页面权限。

操作权限控制:操作权限主要控制用户哪些按钮可以点击,哪些按钮不可以点击。我们可以在管理后台动态为每个页面定义功能标识,在获取用户菜单时把该角色的功能标识一并返回,通过检查当前用户是有有这个标识来判断是否有相应的操作权限。

数据权限控制:我理解的数据权限控制是角色有哪些接口调用的权限,防止用户跨权限调用接口,我们需要把接口和功能点关联起来,调用接口时后台检测当前用户的角色是否有调用该接口的权限,如果没有权限则返回失败。

三、详细介绍

以下介绍以下我根据我的想法实现的权限管理功能(项目可能还有需要改进的地方,欢迎各位大神指点O(∩_∩)O~)

1.、工作台预览

以下是目前正在开发系统的整体布局,基于React.js+Antd pro5.0开发,左侧菜单列表可以通过角色控制,不同角色返回的菜单不一样。

2、菜单管理

菜单管理是管理系统中菜单以及每个菜单中都有哪些功能权限和API权限等。

这里需要配置当前菜单(一级菜单可以不配置)下的所有功能标识(定义前端的功能点,比如列表,编辑,查看,删除等权限)以及该功能对应API权限标识(我后台使用的是Spring Security框架,API标识对应@PreAuthorize注解中的标识)。配置API标识时无需手动一个个输入,有后端接口返回所有API表示列表,从过年下拉框中选择即可。

为每个功能点指定API标识后,后端可以控制只有拥有该功能权限的角色才可以调用该API,从而做到数据权限控制。

后端可通过以下代码获取所有已注册的API权限标识,然后返回给前端,

Set<String> authSet = new HashSet<>();Map<String,Object> beans = applicationContext.getBeansWithAnnotation(Controller.class);
for(Object bean : beans.values()){Method[] methods = bean.getClass().getMethods();for (Method method : methods) {PreAuthorize anno = AnnotationUtils.findAnnotation(method, PreAuthorize.class);if (anno != null) {String val = anno.value();if (val.indexOf("hasAuthority") >= 0 || val.indexOf("hasAnyAuthority") >= 0) {val = val.substring(val.indexOf("(") + 1, val.indexOf(")"));String[] authArray = val.replace("'", "").split(",");for (String auth : authArray) {authSet.add(auth);}}}}
}

3.权限管理

权限管理是配置菜单中有哪些功能点以及各个功能点有哪些API权限,跟上面菜单管理中的功能一样,只是提供2个入口配置,通过菜单管理中的权限管理配置入口可以为做到为菜单批量配置权限,这里需要一个一个的添加。

4. 部门管理

管理公司部门,支持分级管理。

5、用户管理

这个没有什么好说的,就是管理用户信息的地方。这里其实有2个可以优化的地方,一个用户应该可以对应多个角色,以及一个用户可以对应多个部门,这一块我简化了一下,每一个用户只有一个角色,每个用户只能对应一个部门。

6.角色管理

角色可根据自身系统业务需求,随意增删改查,无需事先定死角色类型,每个角色后面有一个权限管理入口,在那个页面给么给角色动态分配权限。

这里会列出当前菜单拥有的所有功能权限,可以给当前角色赋予指定权限

由此后端的权限配置就完成了

7.前端菜单展示和权限控制

用户登录以后,后端验证用户,根据用户的角色获取对应菜单信息和功能权限列表返回给前端,

菜单列表格式如下:

功能权限列表格式如下:

修改前端的routes.ts文件,设置菜单的access值为上图对应的功能标识。

修改app.tsx和access.ts文件,配置后端返回的功能权限列表以及用户菜单。

app.tsx:

export async function getInitialState(): Promise<{settings?: Partial<LayoutSettings>;currentUser?: CurrentUserInfo;config?: ConfigInfo;access?:any;menuData?:MenuNavItem[];fetchUserInfo?: () => Promise<BizInfo<CurrentUserInfo>>;fetchUserPerms?: () => Promise<BizInfo<any>>;fetchUserNav?: () => Promise<BizInfo<MenuNavItem[]>>;getAccess?:(perms: any) => any;}> {const fetchUserInfo = async () => {//调用接口获取用户信息,代码省略。。。};const fetchUserPerms = async () => {//调用接口获取用户功能权限,代码省略。。。};const fetchUserNav = async () => {//调用接口获取用户菜单,代码省略。。。};const getAccess = (perms: any) => {let defaultData = Object.create(null);initDefaultAccess(defaultData, routes);let access = {...defaultData, ...perms};if (!access) {access = Object.create(null);}return access;}let config = undefined;const configData = await getConfigRequest();if (configData.state === ErrorCode.SUCCESS) {config = configData.data;}// 如果是登录页面,不执行if (history.location.pathname !== loginPath) {const currentUser = await fetchUserInfo();const perms = await fetchUserPerms();const menus = await fetchUserNav();return {fetchUserInfo:getCurrentUserRequest,fetchUserPerms:getSelfPermRequest,fetchUserNav: getSelfNavRequest,getAccess: getAccess,currentUser,config:config,settings: {},access:getAccess(perms),menuData:menus,};}return {fetchUserInfo:getCurrentUserRequest,fetchUserPerms:getSelfPermRequest,fetchUserNav: getSelfNavRequest,getAccess:getAccess,config:config,settings: {},};}

access.ts:

export default function access(initialState: { access?: any }) {const { access } = initialState || {};if (!access) {let defaultData = Object.create(null);return defaultData;}return access;
}

在页面中可以通过以下代码获取该角色是否有指定功能权限

canAccess('SYS_MENU_ADD', access);

如上面的代码,如果权限接口返回的功能权限标识中SYS_MENU_ADD=true,则该canAccess函数放回true,由此可以控制页面中是否显示指定按钮或内容块。

四、总结

以上是个人总结的一套权限管理解决方案,优点是可以通过管理后台界面对角色权限动态配置,无需修改代码。大家如果有什么其他更好的解决方案,希望能多多交流,学习学习。

五、其他

以上哪里写的不对或者有待改进,欢迎大家提意见,谢谢!
转载请注明出处:后台管理系统 – 权限管理 - 罗旭东

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

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

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

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

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

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

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

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

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

  5. 后台管理系统——权限管理

    1.做到权限管理就要让菜单动态生成 后端给我返回,当前登录账户的路径,就像["/home","/produce","/abc"]这样子返回, ...

  6. 后台管理系统 权限管理

    一.实现权限控制 - 基于RBAC权限控制理念 页面权限的思路 1.默认有静态路由,前端本地拥有完整的动态路由,服务器端返回该用户的页面权限标识,筛选出属于当前用户的动态路由,然后通过router.a ...

  7. 后台管理系统权限管理实现步骤

    1.管理员给账户分配角色 通过api接口的调用给用户添加不同的参数字段标识 2.管理员给角色分配权限 通过api接口的调用,将不同的权限参数绑定给相应的角色 3.路由权限 与权限有关的组件路由提取到一 ...

  8. 保险后台管理系统/订单管理/保单管理/客户管理/咨询管理/保险原型/保单详情/客户详情/权限管理/部门管理/账号管理/保险系统原型/汽车保险后台管理系统/角色管理/咨询详情/axure原型/需求文档

    保险后台管理系统/订单管理/保单管理/客户管理/咨询管理/保险原型/保单详情/客户详情/权限管理/部门管理/账号管理/保险系统原型/汽车保险后台管理系统/角色管理/咨询详情/axure原型/需求文档 ...

  9. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框

    文章目录 目标 代码 0.结构 1.按钮-删除 2.按钮-编辑 3.debug 4.样式 5.分页Pagination:功能 6.分页Pagination:样式 7.搜索框:功能 8.搜索框:样式 总 ...

  10. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出

    文章目录 目标 代码 0.页面结构 1.新增按钮和弹出表单:结构 2.新增按钮和弹出表单:点击新增弹出表单 3.表单样式 4.表单验证 5.表单的提交和取消功能:接口.mock相关准备 6.表单的提交 ...

最新文章

  1. 《剑指offer》写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。...
  2. Open***服务器安装配置及客户端调试
  3. 如何学习网络协议(学习笔记)
  4. 管桩的弹性模量计算公式_桩基设计计算公式
  5. 特斯拉:召回不涉及国产车型 也与“刹车失灵”无关
  6. WebAPI和Node
  7. 灵活强大的MySQL代理中间件ProxySQL应用实战(2)
  8. php json替换,php解决json中中文部分被替换为unicode编码
  9. BiLSTM-CRF模型理解
  10. Xmodem、Ymodem和Zmodem协议是最常用的三种通信协议
  11. SPSS——描述性统计分析——比率分析
  12. java rrd 读取_RRDtool 系列连载-6 :如何从 RRD 数据库中提取数据 - RRDtool - 阿勃的 blog...
  13. win8页面 html,Win8 Metro风格界面设计HTML+CSS网页模板
  14. lombook插件安装
  15. 十六进制编辑器HxD Hex Editor x64 v2.3.0.0
  16. 读书笔记2区块链与大数据
  17. 极速办公(PPT)如何设置幻灯片大小
  18. Linux 中的TAB键妙用
  19. stm32 pwm频率与周期计算
  20. [日常笔记] 2: 本地视频播放器 MPV

热门文章

  1. PTA平台之温度转换
  2. 搭建第一个springBoot 摘抄自蚂蚁课堂
  3. BT种子结构及bencoding编码解析
  4. Dsoframer控件的下载及注册
  5. 【OEIS】Xor Sum AtCoder2272
  6. 情人节送对象什么礼物好?适合送男友的礼物
  7. UI 自动化框架对比2
  8. Java基础编程题:倒序输出九九乘法表
  9. paddlehub 使用体验-视频抠图_乘风破浪的姐姐_人美路子野 2020-08-13
  10. c语言万能头文件用不,万能头文件不能用?