简介近年来,随着react、angular、vue等前端框架的兴起,前后端分离的架构有了迅速走红。但与此同时,权限控制也带来了问题。网上很多前后端分离的权限只是描述了前端的权限控制,都是比较简单固定的角色场景,不能满足我们用户和角色都是动态的场景。而只有前端的权限控制并不是真正的权限控制,只是减少页面结构暴露,提升用户体验的作用。场景系统是一个后台管理系统,包括用户创建、用户登录、用户对自身资源的管理。用户经常添加和删除用户,也可以根据工作情况随时调整页面和功能权限,所以采用用户-角色-页面权限方案。为什么不行:1、左侧菜单是按照前端路由表显示的,但是vue-router的路由表主要是为了代码组织,往往我们需要的菜单并不一致。比如一个前端路由a有子路由b和c,但是在菜单中我们想直接把b和c显示在一级菜单或者把b和c放在其他菜单下。所以这是非常不灵活的。2.路由是菜单还是页面?是否需要在菜单中显示?是否验证了权限?哪个角色或用户有权限?3.如果权限是在前端硬编码的,那么角色或用户必须是已知的和固定的。例如,添加页面1的meta属性,将可访问的角色标识为a和b。页面页面就是一个前端页面,比如首页,用户管理页面,资源管理页面等,基本思路是:前端路由不变,数据库存储菜单结构,页面权限控制(它可以直接做成页面方便管理)等,前端根据数据库中的菜单结构和权限信息渲染一个菜单,只显示其有权限的菜单,进行权限控制out在routeguard中防止手动输入路径未经授权打开页面。1、前端路由(vue-router)需要正常创建页面和路由。2、数据库存储菜单结构和页面权限信息。A。菜单(目录,非内容页面)可以自己创建,不需要包含在前端路由中,因为这里指的是菜单的视觉组织结构。b.页面(内容页面)必须是前端路由中已有的页面,因为这是用户需要访问的。C。菜单和页面形成上下级关系。第一级可以是菜单或内容页面。内容页也可以放在菜单下,不可见的内容页也可以放在普通内容页下。这个理论(需要页面Menu样式支持)可以形成无限级菜单。面包屑也基于这个层次递归搜索。d.菜单和页面的基本属性包括title(对应路由标题)、name(对应路由名称)、path(对应路由路径)、parent、type(菜单/页面)、是否可见(左边是否可见)菜单栏显示:页面中可能链接部分页面),是否需要验证权限(部分页面,如首页,无需验证权限,所有人均可访问)。e.不需要控制权限,不需要在左侧菜单显示的路由,这里可以不管理,比如404页面等。3.前台打开后,获取前台的所有菜单、页面和结构数据库,根据是否登录、是否验证权限、未经许可跳转到登录页面进行控制。4.用户登录成功后,获取用户对应的页面权限列表,将上一步获取的所有页面、结构、用户权限列表渲染成一个菜单,只包含用户权限,提高用户身体检查,以避免显示大量用户无法访问的菜单,影响使用并暴露不必要的功能。5、路由守卫根据上一步得到的权限列表判断每次跳转。如果没有权限,可以返回404或者没有权限的页面,防止用户手动输入路径进行未经授权的访问。页面管理:页面编辑:部分功能需要单独控制权限。例如,用户管理页面可能允许多个角色查看,但“创建用户”功能只允许某个角色使用,因此仅使用页面权限是不够的。因此需要细粒度的功能权限控制。网上的解决方案都说:基于资源控制增删改查,比如用户的创建、修改、删除、查询。但是,在我的实际使用中,发现并不实用。至少像我这样的管理背景,资源不是简单的增删改查。其他地方可能还有其他操作也会影响到这个用户资源,比如禁用删除一个角色也需要禁用删除一个用户,那么这个权限是属于角色的还是属于用户的,或者后台是否发生了变化,角色影响其他资源或不再对用户进行操作,都会影响权限控制。因此,更合理的做法应该是对每个功能进行单独控制,并与页面关联起来,而不局限于增删改查。可以任意定制,只需要和前后端开发商定一个唯一标识即可。上面的例子中,在用户管理页面下有各种用户功能,在角色管理页面中还有一个角色禁用和删除功能,可以分别定义为role_disable和role_delete。如果你有role_delete权限,即使你没有user_delete权限也可以。直接删除用户,否则不要赋予role_delete权限。用户登录后,从数据库中获取其拥有的权限列表,保存在vuex中,包括页面和功能的对应关系。比如页面名称为user:{user:['user_delete','user_query']},页面删除根据按钮可以通过v-if="hasPermission('user_delete')"来判断.页面功能管理:获取用户拥有的权限:角色角色类似于身份或职位,每个角色都有自己的权限范围。一个角色可以有多个页面权限。一个角色可以有多个功能权限。角色管理:角色分配权限:可以创建和删除用户用户。一个用户随时可能改变工作内容,或者承担多个角色,因此可以为他分配一个或多个角色,他所拥有的角色的权限就是他的权限。至此,就可以打通权限前端的权限分配,用户-角色-页面权限,功能权限。用户管理:用户分配角色:前端作用前端页面菜单作用:后端权限传统上,在前后端不分离的情况下,路由都在后端管理。简单的方法比如用户管理页面/user/然后里面用到的接口都是用相同的前缀比如/user/add,/user/delete等等所以只要判断用户有/user/权限,他可以访问/user/*的所有接口。前后端分离后面临的问题:接口方案:1.上传管理需要控制权限的接口(可以做成管理页面)2.每个页面和功能可以关联多个接口,用于例如,用户页面关联用户查询界面和用户编辑界面,用户删除功能关联用户删除界面3.后台判断请求的路径,用户->角色->页面/功能->界面,并且有接口权限才允许访问4.前后端都是团队开发的,不方便一一比较,而且前端有自己的路由(这个路由受限于代码组织结构)等,这是传统方法无法轻易处理的。5、同一个界面可能被多个前端页面多次使用。接口管理:页面关联接口,功能关联接口:当请求的接口没有权限时:接口后台权限控制后台控制其实很简单,只要做好前面的管理功能,基本逻辑是:1.用户访问界面。2.确定用户和当前路径,按照User->Role->Page/Function->Interface比较当前用户有权限的接口列表和当前路径。3.如果没有权限(有些接口需要登录才能访问,比如需要获取用户名信息除外),直接返回失败,前端会提示no全局捕获后的权限。总结1.用户管理a.添加、删除、修改和查看用户b.为每个用户分配一个或多个角色2.角色管理a.添加、删除、修改和查看角色b.为每个角色分配一个或多个页面,功能授权3.页面管理a.增加、删除、修改和查看页面b.标记页面的上下层结构,是否为内容页面(需要对应前端存在的路由页面),是否可见,是否控制权限等。c.前端菜单、面包屑等按照上下结构等方式渲染用户可感知的内容,不受前端代码中路由的限制d.前端路由根据这个权限表进行权限控制4.接口权限控制a.界面管理进入需要控制权限的界面b.将界面分别与页面和功能相关联c.有function权限就有相应的界面权限,有page权限就有相应的权限d.只要你有界面权限通过任何页面和功能都可以访问这个界面
