‘壹’ 后台管理系统 权限分配前端怎么分配
1、最简单的就是登陆控制了。
2、然后是简单的权限控制到功能(页面),这时候你需要知道数据表怎么设计,
SQL怎么查询,代码如何判断。
3、再往上就开始考虑角色的设计。
4、考虑功能细节的控制(新增、更新、删除、...)
5、考虑Scalability、Performance、User-Friendly....
‘贰’ Vue前端用户权限控制大全
用户权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源
接口权限目前一般采用通用的形式来验证(用户是否登录系统),没有的话一般返回401,跳转到登录页面重新进行登录 ,
登录成功后拿到token,将token存起来,通过axios请求拦截器进行拦截,每次请求的时候头部携带token
通过自定义指令进行按钮权限的判断
自定义权限指令
在使用的按钮中只需要引用v-has指令
全局路由守卫里做判断
每次路由跳转的时候都要判断权限,这里的判断也很简单,因为菜单的name与路由的name是一一对应的,而后端返回的菜单就已经是经过权限过滤的
如果根据路由name找不到对应的菜单,就表示用户有没权限访问
如果路由很多,可以在应用初始化的时候,只挂载不需要权限控制的路由。取得后端返回的菜单后,根据菜单与路由的对应关系,筛选出可访问的路由,通过addRoutes动态挂载
这种方式的缺点:
菜单需要与路由做一一对应,前端添加了新功能,需要通过菜单管理功能添加新的菜单,如果菜单配置的不对会导致应用不能正常使用
全局路由守卫里,每次路由跳转都要做判断
‘叁’ 前端如何控制用户权限
1. UI处理(根据用户拥有的权限,判断页面上的一些内容是否显示)
2. 路由处理(当用户访问一个它没有权限访问的url时,跳转到一个错误提示的页面)
3. HTTP请求处理(当我们发送一个数据请求,如果返回的status是401或者401,则通常重定向到一个错误提示的页面)
如何实现?
首先需要在Angular启动之前就获取到当前用户的所有的permissions,然后比较优雅的方式是通过一个service存放这个映射关系.对于UI处理一个页面上的内容是否根据权限进行显示,我们应该通过一个directive来实现.当处理完这些,我们还需要在添加一个路由时额外为其添加一个"permission"属性,并为其赋值表明拥有哪些权限的角色可以跳转这个URL,然后通过Angular监听routeChangeStart事件来进行当前用户是否拥有此URL访问权限的校验.最后还需要一个HTTP拦截器监控当一个请求返回的status是401或者403时,跳转页面到一个错误提示页面.
大致上的工作就是这些,看起来有些多,其实一个个来还是挺好处理的.
在Angular运行之前获取到permission的映射关系
Angular项目通过ng-app启动,但是一些情况下我们是希望Angular项目的启动在我们的控制之中.比如现在这种情况下,我就希望能获取到当前登录用户的所有permission映射关系后,再启动Angular的App.幸运的是Angular本身提供了这种方式,也就是angular.bootstrap().看的仔细的人可能会注意到,这里使用的是$.get(),没有错用的是jQuery而不是Angular的$resource或者$http,因为在这个时候Angular还没有启动,它的function我们还无法使用.
进一步使用上面的代码可以将获取到的映射关系放入一个service作为全局变量来使用.
在取得当前用户的权限集合后,我们将这个集合存档到对应的一个service中,然后又做了2件事:
(1) 将permissions存放到factory变量中,使之一直处于内存中,实现全局变量的作用,但却没有污染命名空间.
(2) 通过$broadcast广播事件,当权限发生变更的时候.
如何确定UI组件的依据权限进行显隐
这里我们需要自己编写一个directive,它会依据权限关系来进行显示或者隐藏元素.
这里看到了比较理想的情况是通关一个has-permission属性校验permission的name,如果当前用户有则显示,没有则隐藏.
扩展一下之前的factory:
路由上的依权限访问
这一部分的实现的思路是这样: 当我们定义一个路由的时候增加一个permission的属性,属性的值就是有哪些权限才能访问当前url.然后通过routeChangeStart事件一直监听url变化.每次变化url的时候,去校验当前要跳转的url是否符合条件,然后决定是跳转成功还是跳转到错误的提示页面.
router.js:
mainController.js 或者 indexController.js (总之是父层Controller)
这里依然用到了之前写的hasPermission,这些东西都是高度可复用的.这样就搞定了,在每次view的route跳转前,在父容器的Controller中判断一些它到底有没有跳转的权限即可.
HTTP请求处理
这个应该相对来说好处理一点,思想的思路也很简单.因为Angular应用推荐的是RESTful风格的接口,所以对于HTTP协议的使用很清晰.对于请求返回的status code如果是401或者403则表示没有权限,就跳转到对应的错误提示页面即可.
当然我们不可能每个请求都去手动校验转发一次,所以肯定需要一个总的filter.代码如下:
写到这里我们就基本实现了在这种前后端分离模式下,前端部分的权限管理和控制。
‘肆’ 系统权限设计思路方法总结
几乎所有的管理后台都会涉及到权限的设计,权限控制是管理后台的重要功能,可以有效的提高系统的安全性,减少误操作、数据泄漏等风险的发生。但是,很多产品经理会对权限功能有一点害怕的心理,一方面是由于能参考的实例较少,权限管理算是一个“系统级”的基础功能,一般系统中只有管理员可以操作,不像其他功能可以通过去其他系统中试用体验,另一方面,对于权限功能普通用户无法操作使用,所以存在感较低,做好了也不会出彩,可没做好就会导致整个流程不通、产品崩溃。
一 RBAC模型
目前,接受度较高的功能权限模型是RBAC(Role-Based Access Control)模型。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。
1.角色的作用
如果没有角色的概念,直接用户对应权限,虽然会更加灵活,但是后台的数据表设计会变得复杂,操作成本也会很高,同时容错能力也会变得很差。
而引入“角色”概念后,用户与角色可为多对一或多对多的关系,当一个用户的角色为多对多时,当前用户的权限是多个角色的并集。此时只需要为角色赋予权限,能够大大减轻管理负担,同时将用户与权限解耦,提供更大的灵活性,同时整个设计的容错能力也提高了很多。
2.引入用户组
一些大型的平台上,如果用户数量较大,新增角色时,需要为大量用户分配新的角色,工作量巨大,此时可以引入用户组的概念,将这些用户拉到同一个用户组中,然后对整个用户组进行角色的指定,这就大大减少了角色分配的工作量。
同理如果权限较多时也会存在一样的问题,对角色进行权限设置时也需要大量的操作,此时可以考虑引入权限组的概念,将关联性较强的权限大包成组赋予角色,从而减少赋值时的工作量,现实中权限组的使用相对较少,因为系统中的权限一般来讲是有限的。需要注意的是即使有用户组或权限组的存在,也可以允许用户或权限与角色直接关联,这个可以视具体业务情况而定。
下图所示为mac系统中运行添加用户组,并以用户组为单位配置权限。
3. 角色继承的RBAC模型
在一个业务场景中,如果角色需区分:设计主管、设计组长、设计成员,并且管理方式为向下兼容时,则需使用角色继承的RBAC模型。上层角色继承下层角色的全部权限,且可额外赋予权限。
此时除了对角色进行定义,还需要管理角色间的关系,通过关系来体现角色的层级关系,从而达到继承权限的效果。角色的继承关系主要有两种:树形图和有向无环图。
继承关系常常来源于公司团队的组织结构,此时常将角色与组织结构进行关联达到继承角色模型的效果。如下图所示的赵同学,其角色是“三级团队负责人”,与其并列的小组中有多个“三级团队负责人”的角色,但依附于左侧的组织结构树,各级负责人仅有查看和操作自己下属子节点的权限。
4. 限制的RBAC模型
在一个产品或系统中,部分角色可能是需要隔离的、不允许被同时赋予一个人的。跟大家熟知的“不能既是‘运动员’又是‘裁判员’ ”一个道理。
因此,对于众多角色中的一组,只能是单选的关系,但多组角色之间可以共同存在。如下图中,一个用户可以既为设计师又为管理员,但在设计师角色组中仅能被赋予一个角色,在管理员角色组中也仅能被赋予一个角色。
此外,限制还有可能是数量上的,比如一个产品组中必须有且只有一个管理员,不允许删除或再分配管理员角色,仅允许将负责人角色变更。
限制的模型不仅仅对分配过程产生影响,有时即使拥有了多种角色,因为不同的角色对同一个功能的使用方式或数据会产生冲突,所以使用时也需要进行限制。如下图所示为同一时间仅允许以一个身份登录。
根据不同的业务需求,限制的形式很多。需要注意的是不能仅依赖后端限制,而是要在前端展示清晰的规则和恰当的限制,避免用户出错和沮丧。
三、权限的拆分与设计
通过RBAC模型已经能够很好的搭建起用户、角色与权限之间的关系了。但具体是什么样的关系,以及“权限”这个抽象的概念具体如何规划?
这些都需要分析清楚才能进一步设计出完善的权限系统。
首先需要知道,一般产品的权限由页面、操作和数据构成。页面与操作相互关联,必须拥有页面权限,才能分配该页面下对应的操作权限。数据可被增删改查。
整体关系如下图所示:
因此,在设计之初我们就需要考虑到未来可能区分角色的地方,尽量解耦、模块化。对于技术来说,每一个页面模块、每一个操作都最好使用独立的接口。对于设计来说,需要保障所有角色因为权限而屏蔽掉部分操作和数据后,页面和流程仍能体验流畅。
保证初期设计支持后,配置权限时,还需要注意以下几点:
(1)确定是否支持前端配置
如果角色和权限相对固定,则一般将角色与权限的关系可以写在后台,改动时需要后端变更且重新上线。这种情况适用于公司内部系统等只有一个使用主体的系统。
如果需要自定义角色或者每个角色在不同使用者的场景下有不同的权限,则需要将角色的定义、角色与权限之间的配置体现在“前端用户配置页面”。这种情况适用于有频繁变动的自定义角色权限,和有租户体系的系统。
(2)以基本单元拆分,以业务逻辑配置
一般可将每个对象的“增、删、改、查”各自作为一个基本的权限单元。打个比方,在“人员管理”中,查看人员列表、添加人员、删除人员、编辑人员信息最好拆分为4个权限单元。在技术和设计上,我们希望能尽量做到解耦和模块化。
但是在业务层面有些操作却是一体的。这些不能拆开的权限在“前端用户配置页面”中建议打包成一个整体提供配置。例如:如果我们确定在系统的现有和未来业务中,仅分为普通成员有“人员管理”的查看权限,管理员有操作权限,则可将“增、删、改”三个基本权限单位合并为“操作”权限进行配置。
(3)页面权限优先于操作和数据权限
必须配置了页面模块权限后,才能配置当前页面模块下具体的操作权限,以及页面模块的数据展示权限。
(4)查看权限优先于增删改权限
正常情况下,一定要先能查看某个模块或操作,其它的增删改操作才有意义。因此在设计时,应在获取查看权限前限制其它权限的配置,或者配置其它权限时默认赋予查看权限。
(5)角色与权限的多种关系
角色与权限的关系不仅是单纯“是/否关系”,还包括以某种限制进行操作,和以某种程度访问数据。
例如在“人员管理”中:
数据范围:用户拥有查看人员列表的权限,但仅能查看自己所在的团队;数据边界限制(上限等):添加人员时不能超过20个等。数据字段:HR能查看人员列表中包括职级、薪资等字段,其它角色仅能查看姓名邮箱等字段;
(6)角色与权限的设计表达
在传达一个系统的权限设计规则时,设计师常常习惯用主观最直接的方式表达想法,如用“当……时,就……”的句式来表达。但一个平台中涉及的权限规则是非常多的,当通篇以这样的形式描述时,表达对象将很难理解。
正确的描述方式:更清晰的是基于开发的语言,和技术模型的结果进行表达。将各角色与权限单元绘制成网格,每个交叉点网格中描述该角色与权限的数据关系和限制。
如下图所示:
四、需要注意的Tips
1. 隐形的admin
在可自定义角色和权限的系统中,一般需要预留一个admin角色来进行系统的初始配置,用于添加首批的业务人员和配置基本的角色。
有的系统中允许存在上帝视角的admin角色,则其可以作为“超级管理员”显示在角色配置的列表中。有的系统中不允许这种角色存在,则可将这种角色设置为隐形的状态,仅赋予维护系统的工作人员。
2. 初始权限的赋予
对于允许用户自行加入的系统,需要设定一至多个默认的角色,有时可以是仅有最基础权限的“游客”角色。
初始权限还可以与用户既有的某些数据字段进行关联,如添加用户时获取到用户的岗位为“设计师”,则直接赋予“设计师”角色的权限。
3. 人员管理中对自己的处理
在人员管理中,管理员角色处理自己时需要额外注意。因为如果修改或删除了自己角色后,可能导致系统没有管理角色,从而无法添加其他成员和正常运行。设计时可添加判断,当自己为唯一管理角色时,禁止编辑和删除。
4. 无页面权限的提示
虽然可以通过页面权限限制直接隐藏当前用户没有权限的页面,但不能排除用户获取到权限外的url地址。当用户意外访问到没有权限的页面时务必提供“无权限”的提示,避免用户认为系统bug。
总结一下,整个权限系统设计就是定义各个节点和节点间关系的过程。
节点包括:
用户;用户组;角色;角色组;权限(页面、操作、数据);权限组(页面、操作、数据);
‘伍’ 前端权限控制
前端权限控制分为四个方面的控制
第一点界面控制:用户还未登入就能通过url访问到系统页面,该问题比较好解决通过路由守卫即可判断。
如果用户登入以后用url访问不是属于自己的菜单页,如我没有系统管理这个界面,我去地址栏输入系统管理这个页面的url,前端因该阻止它访问页面。输入url能访问到页面的原因是你的路由配置了这个地址,所以控制界面的方式就是从路由入手,前期我们配置大家都有的路由,其他的路由根据登入系统时后台返回的权限列表数据,动态添加路由。
在登入时我们把权限数据存入vuex中并本地化,通过路由对象可以获取到路由的配置,把那个用户的路由单独添加到路由列表中,使用addroutes添加更改后到路由配置,添加动态路由的方法调用在app.vue的created中,因为每次加载页面都会调用该方法。
第二菜单控制:
根据用户的不同菜单栏也不同,该问题跟动态路由类似登入时拿到数据存入vuex中并本地化,之后在菜单组件列表循环遍历出对应的菜单栏,过于简单就不截图了。
第三按钮控制:
这个控制可以采用自定义组件的方式,例如这个用户没有添加人员的按钮,他只有查看这个人员菜单的权限。在页面上按钮都添加上,但是是否能显示则根据后端传过来的权限数据,该数据在动态路由作为meta数据添加在路由上了,也就是用路由的meta的数据去判断这个按钮是否显示或者禁用或是可用,在页面我们添加按钮我们就加一个action属于为add,我们或者add去比较如果没有add这个权限如果处理。上图
第四请求拦截
请求拦截并不简单的做一个token,而是每个用户对应可以操作的请求放行,不是他可以操作的拦截,如他没有添加的请求则要拦截,前面不是做了按钮的控制吗,为啥还要做这个拦截,按钮控制并不安全,其实他可以通过浏览器直接修改按钮的属性,有人又说有token了不是可以拦截了吗,对,可以拦截不过那时后台拦截,你请求还是发过去了,请求影响系统性能,所以做这个还是有必要的。
请求拦截,根据名字就知道他是在请求拦截器里设置的,在拦截器中可以获取请求方式,根据请求方式与路由中的mate权限对比有就发送请求,如果没有则不发请求
‘陆’ 谈前端权限
自从有了前后端分离,前端的工作内容就变得越发多起来,其中有一项就是权限控制,下面就谈一谈前端权限。
首先我们要理清前端权限是什么,我理解的前端权限就是 控制前端元素是否可见 。因为之前后台模板时代,我们的页面都是通过后台来渲染的,能不能访问到页面直接由后台逻辑判断就好。但是现在我们到了前后端分离时代,所有页面的元素都由页面本身来控制,所以页面路由这块需要由前端本身来控制了。所以我认为前端权限有这几个关键点:
下面我们说一说为什么说 前端只能做视觉上的控制 和 权限控制不能放在前端,后台还是需要对每一个接口做验权 。我觉得其实WEB本身就是围绕数据来的,所以我们前端安全,主要是保护我们的 数据 ,那和数据最紧密接触的其实还是后台,前端本身做得是 数据的展示和收集 ,但是数据的存储和处理并不是由前端来做。所以即使前端能控制住路由/按钮等不被别人看到,发送请求的方式还是有很多,完全可以绕过前端来请求数据。所以从某种意义上来说,就算前端的权限控制做得再严密,可能作用也是有限的。这也引申了后面一句,后台还是要对每一个接口做验权。
但是前端做权限控制还是非常有意义的,我觉得在安全性方面来说,前端就显示人体的皮肤,我们会是WEB安全的第一道防线。前端要做的工作,我认为有三种:
博客地址 北落师门
‘柒’ Vue实现动态路由
通常我们在vue项目中都是前端配置好路由的,但在一些项目中我们可能会遇到权限控制,这样我们就涉及到 动态路由 的设置了。
动态路由设置一般有两种 :
(1)、简单的角色路由设置:比如只涉及到管理员和普通用户的权限。通常直接在前端进行简单的角色权限设置
(2)、复杂的路由权限设置:比如OA系统、多种角色的权限配置。通常需要后端返回路由列表,前端渲染使用
到这里,整个动态路由就可以走通了,但是页面跳转、路由守卫处理是异步的,会存在动态路由添加后跳转的是空白页面,这是因为路由在执行next()时,router里面的数据还不存在,此时,你可以通过window.location.reload()来刷新路由
后端返回的路由格式:
注意: vue是单页面应用程序,所以页面一刷新数据部分数据也会跟着丢失,所以我们需要将store中的数据存储到本地,才能保证路由不丢失。关于vue页面刷新保存页面状态,可以查看 vue如何在页面刷新时保留状态信息
‘捌’ 前端的权限控制
1.菜单的控制
在登陆请求中,回到的权限数据,这个权限的数据是后端返回的数据,前端根据权限数据,展示对应的菜单,点击菜单,才能看到相关的界面。
2.界面的控制
如果用户没有登录,手动在地址栏中输入管理界面的地址,则页面会跳转到登录界面,
如果用户已经登录,但是手动输入非权限内的地址,则会跳转到404界面中去。
3.按钮的控制
在某个菜单的界面中,还需要根据权限数据,展示出该权限范围内可以操作的按钮,比如增删改查
4请求和相应的控制
如果用户通过非常规的操作,比如通过浏览器的调试工具将某些禁用的按钮变成了启用的状态,这个时候发的请求,也应该由前端所拦截。
‘玖’ 产品经理要做的操作权限/数据权限设计
产品经理在工作中还需要知道一个:用户权限设计能力。权限设计理念贯穿于后台产品、以及用户前端产品。
权限能力包括两类:数据权限、系统操作权限
有的人会好奇,为什么前端产品会有有权限管理的要求?接下来我将以角色、权限、以及RABC权限设计方法来概述权限设计、数据权限设计2个操作。
了解权限系统前,首先要定义角色,角色的分类如下
最高权限角色
超级管理员,这个角色一般为平台创建者。可以拥有最高权限,可分配所有的系统权限到其他用户,一般是把最高权限设计还会映射一个超级管理员作为副管理,方便删除、编辑人员
副管理员角色
副超级管理员,仅次于最高权限,可以分配自己权限下的以外权限。显然在他之上就是超级管理员权限
部分权限所有者角色
是指的是在副管理员下,有子权限的用户。比如在副管理员分层下的权限
特约用户角色
只是定向权限开通,同事这样的用户有大量的。比如PMTalk产品经理社区的签约作者
付费用户角色
付费用户权限在针对产品生命周期早期是与免费直接区分,随着付费用户精细化运营打造用户分层,比如QQ会员的超级会员、普通会员等
角色之间的关系如下,可以看见在超级管理员角色下以树状结构分布到子角色。
▲ 角色之间关系
基于角色权限控制的RABC权限思想
依次为理论的角色设计模型关系图
▲ RABC角色权限
上图是基于用户的会话集合归位角色再分配权限。角色有操作和控制对象的权利,在基础上将用户权限系统氛围:用户管理、角色管理、权限管理。
实际上用户管理在系统早期是可以满足权限使用,但随着系统用户、公司扩张逐渐增多,可能用户会有因为部门的职责区别,造成了部门下的同用户权限是一样的。
因此产品经理务必要在用户管理上增加部门管理对角色区分。
▲ 部门管理
将部门架构的编辑、添加、管理都以系统化的方式管理。
看到部门之间的流转关系,还可以知道部门下有什么基础权限。比如运营部门肯定会涉及到公众号管理、客服号管理,所以在以下部门的员工都要求设置。
同个部门中存在多个角色,比 如上有运营总监、副总监、组长、用户,因此权限要给到每个部门负责人进行编辑、删除、添加。
让权限管理者降低了日常运营权限工作量,将权限分配能力分配给了其他成员。
▲ 网上来自部门角色权限管理的配置图
用户管理,给与用户授权角色
最普遍的做法是设计用户名单列表,针对用户信息进行编辑。
用户管理列表如上,可以操作用户属于封禁状态与否、查看用户先有状态。
每个角色下的权限设置,可以编辑权限、和删除权限。以及批量同意权限
设置好角色后,还可以在角色下查看已经开通的用户名单,对用户名单进行管理。
用户名单进行删除、添加。同时当前页面需要下可以展示多少用户、是否需要分页也要注意明确。
2.添加/创建用户
为系统添加新的管理人员,增加权限。增加手机号、邮箱、用户名称,如果企业使用了OA系统,可以和OA系统进行关联。
比如现在的企业微信、钉钉都是支持开放接口,快速同步员工信息。
3.创建添加账户管理流程
系统建设好后,接下来就是规范运营了。以账户开通来说要建立账户开通权限流程规范,比如下图是某个公司开通运营系统管理员权限的流程
▲ 系统权限创建流程
上图“选择字段”可以理解为权限下的子权限。若系统不复杂可以不用在早起权限设计上增加子权限颗粒度。
我们需要先设置角色,给新账号关联对应的角色,如果账号有特殊权限或者相关字段的权限,再单独设置相关字段。
最后基于RABC角色权限系统设置,产品经理可以借鉴的一个思考脑图案例
完成权限设计后,要搭建权限表单。快速罗列各个角色下的权限通道
▲
数据权限的设计
操作权限是比较容易做的,但数据权限则比较难了。甚至许多互联网公司都没有考虑数据权限,只要达到不同人员使用的功能不同即可。
数据权限可以控制组织、可以控制数据域(比如,10个门店,有的人能看到1个门店的数据,有的人能看到10个门店的数据)
做个比喻,功能权限就像是容器,觉得了你有什么功能,数据权限就像水,决定了你容器内放的是什么。功能权限和数据权限是相互独立的。
数据权限是指对系统用户进行数据资源的可见性、以及控制性。直白说:“复合条件的用户才能查看和操作对应数据的权限”
比如公司老板需要看到公司的营收、利润、用户增长数据
公司运营总监需要看到互联网产品业务营收
公司公司销售要看实物销售产品的以后
在数据权限设计下,要定义清楚规则元
名词定义:规则元。在本文是指单个独立的数据规则定义,不同用户对规则元可设置具体的规则过滤值,该值用作数据查询时的筛选条件。
规则元配置:规则元名称的配置。一个表中哪些字段可以进行规则设置,以及规则元名称如何与表字段关联。
‘拾’ 前端权限控制时要考虑的5个问题
1.登录控制 哪些页面不需要登录就可以进入
实现思路: 在路由配置metal里配置是否需要登录 默认需要登录,在路由之前的钩子里进行判断
2.路由控制 不同角色访问不同的页面
实现思路:路由配置分成静态路由和动态路由,动态路由部分按权限返回的结果进行动态加载
3.页面上的操作按钮控制 不同的角色在同一个页面 可以点击的按钮不同
写一个命令进行操作控制
4.列表上增加删除修改 控制 在获取列表数据是返回显示哪些按钮
5.菜单显示控制 根据不同的角色显示不同的菜单
6.账号切换时 重新加载对应路由