# 权限控制设计 重要

权限控制主要分为前端菜单、页面按钮后端接口控制,一个安全严谨的系统在这几个方面缺一不可,尤其是后端接口的权限控制,当然如果一些对权限安全方面要求不是很高的系统,控制好前端也是可以的了。

题外话

我见过了非常非常多的企业内部管理系统,后端接口的权限控制非常简单,只需有登录的用户就都可以访问。也就是只要我知道接口地址,那哪怕我只是一个普通没有权限的用户,我也可以随便调用接口访问我没有权限的功能。

系统目前是以读(Read)、写(Write)、审核(Review)三个类型进行权限限制,当然这个可以由开发者进行修改的。

具体的权限控制是在角色管理菜单进行配置的,如下图所示,勾选了菜单前面的复选框,说明该角色拥有该菜单的页面访问权限,勾选后菜单的读、写、审核复选框才可选(菜单所具有操作权限需根据菜单的权限配置),勾选对应的操作权限后,该角色拥有菜单对应的操作权限,也拥有菜单的接口上对应权限接口访问权限。

角色编辑窗口

# 前端元素控制

就是控制没有权限的用户打开页面后,相关权限按钮或其它元素被隐藏或禁用了,例如没有读权限的用户,打开页面后,发现查询按钮是灰色的,列表没有数据,没有写权限的用户,创建跟编辑按钮是灰色禁用或者隐藏了。

最初我是想用指令,例如v-permission:read类似这样,然后没有权限就隐藏元素,但后面发现这样太不方便了,例如有些用户可能不想隐藏,想禁用,或者要显示一个提示之类的。最终还是用方法返回Boolean值的方式,这样处理起来更灵活。

我在Vue对象注入了$permission对象,可以用this.$permission访问这个对象,这个对象提供了4个判断是否有对应权限的方法,可详见前端源码/src/utils/permission.js文件,开发者可根据方法返回的Boolean值对前端元素进行隐藏或者禁用。

//以下4个方法均返回Boolean类型的值

//判断当前用户在用户管理菜单上是否有读权限
this.$permission.canRead("sys.user")

//判断当前用户在用户管理菜单上是否有写权限
this.$permission.canWrite("sys.user")

//判断当前用户在用户管理菜单上是否有审核权限
this.$permission.canReview("sys.user") 

//判断当前用户是否有用户管理菜单权限
this.$permission.hasMenu("sys.user")

例如,我需要没有写权限的用户,它的创建按钮是要灰色禁用的,就可以这样处理了,相当灵活。

<el-button 
  type="primary" 
  :disabled="!$permission.canWrite()"
  @click="create" >创建
</el-button>

# 严格权限的组件设计

如果某些组件需要严格的权限控制的话,一般将写成两个组件,一个公共组件,一个非公共组件。

  • 非公共组件:组件上面所用的接口一般是用非公共类型的权限接口。
  • 公共组件:用于被其它组件引用,组件上面所用的接口一般是用公共类型的接口;

例如

一个系统里的员工列表需要被很多其它组件所引用,如果只用一个组件一个接口,那这个组件里的接口必须得定义为公共接口。然后在每个需要引用到员工列表的菜单接口配置里加上此公共接口。

如果说员工列表有很多机密字段,不能随便被查看,那么可以创建两个组件,一个有全部字段的列表,用的是非公共接口,一个仅有公共字段的列表,用的是公共接口,那么在员工档案的菜单接口配置的权限接口上加上非公共接口,在其它要用到员工公共列表的菜单接口公共接口上添加公共接口。

# 后端接口控制

在你需要添加权限验证的接口的控制器上加上这个特性[Authorize(AuthorizationPolicies.AuthorizationPolicyNames.ApiPermission)]就会启用接口的验证了。

后端接口

提示

如果后端的接口没有添加在接口管理里,而后端接口加了这个特性了,那统一会返回无接口权限权限的提示。

上次更新: 1/3/2021, 9:01:12 PM