前、后端分离权限控制设计与实现

简述

近几年随着react、angular、vue等前端框架兴起,前后端分离的架构迅速流行。但同时权限控制也带来了问题。

网上很多前、后端分离权限仅仅都仅仅在描述前端权限控制、且是较简单、固定的角色场景,满足不了我们用户、角色都是动态的场景。且仅仅前端进行权限控制并不是真正意义的权限控制,它只是减少页面结构暴露、增强用户体验的功效。

场景

系统为后台管理系统,包含了用户创建、用户登录、用户管理自己的资源。用户经常会新增、删除,也可以根据工作情况随时调整页面、功能权限,所以采用用户-角色-页面权限方案实现。

为什么不行:

  1. 根据前端路由表显示左侧菜单,但vue-router的路由表主要为了组织代码,经常我们所需要的菜单并非一致。比如某个前端路由a子路由有b、c,但菜单中我们想要直接一级菜单就显示b、c或者将b、c各放到其他菜单下。所以这种非常不灵活。

  2. 一个路由是菜单还是页面?是否需要显示到菜单中?是否验证权限?哪个角色或者用户拥有权限?这些都需要写到前端路由里面,一旦有任何权限变动就要大量调整代码。

  3. 如果权限写死在前端,那么角色或者用户必须已知且固定不变。比如页面1的meta增加属性标识可访问的角色为a和b

页面

一个页面即一个前端页面,比如首页、用户管理页、资源管理页等。

基本思路为:前端路由保持不变,数据库存储菜单结构、页面权限控制(可以直接做成一个页面来方便管理)等,前端根据数据库中的菜单结构和权限信息来渲染一个菜单出来并只显示其有权限的菜单,并在路由守卫中进行权限控制防止手动输入path越权打开页面

  1. 前端路由(vue-router)中需要正常创建页面及路由。

  2. 数据库存储菜单结构和页面权限信息,

    a.菜单(目录、非内容页)可以自己创建,不必要求前端路由中有,因为这是指菜单的可视化的组织结构

    b.页面(内容页)必须是前端路由中已有页面,因为这是用户需要访问的内容。

    c.菜单和页面组成上下级关系,一级可以是菜单也可以是内容页,内容页也可以放在菜单下,不可见的内容页也可以放在一个普通内容页下,这样理论(需要页面菜单样式支持)可以组成无限级菜单。面包屑导航也根据此层级递归查询得到。

    d.菜单和页面的基本属性包括title(对应路由title)、name(对应路由name)、path(对应路由path)、父级、类型(菜单/页面)、是否可见(左侧菜单栏是否显示:部分页面可能是页面内的链接进去)、是否需要验证权限(部分页面比如首页无需验证权限大家都可以进入)

    e.不需要控制权限且不需要显示到左侧菜单的路由这里可以不进行管理,比如404页面等

  3. 前台打开后获取获取数据库的所有菜单、页面及结构,根据是否登录、是否需要验证权限等进行控制,或无权限跳转至登录页

  4. 用户登录成功后,再获取用户对应的的页面权限列表,使用上一步获得的所有页面、结构和用户拥有权限的列表渲染出一个菜单,只包含此用户拥有权限的,提升用户体检,避免显示大量用户不能访问的菜单影响使用和不必要的功能暴露。

  5. 路由守卫中根据上一步获得的权限列表判断每个跳转,无权限可返回404或无权限页面,防止用户手动输入path越权访问

页面管理:

image.png

页面编辑:

image.png

功能

部分功能有事需要单独控制权限,比如用户管理页面可能允许多个角色查看,但是其中的“创建用户”功能只允许某一个角色使用,那么仅仅使用页面权限是不够。所以需要细粒度的功能权限控制。

网上的方案都是说:根据资源控制增、删、改、查等等,比如针对用户就是用户的创建、修改、删除、查询等。但是在我的实际使用中发现并不切合实际,最起码对像我这种管理后台,资源并不单纯的增删改查,可能有其他地方的其他操作中也会对此用户资源造成影响,比如禁用、删除角色也要禁用、删除用户,那么这个权限到底属于角色的权限还是属于用户的权限,或者后台又改了,角色又影响了其他资源或者不再对用户进行操作,都会影响权限控制。

所以更合理的方法应该为将每个功能单独进行控制并和页面进行关联,且不限定必须是增、删、改、查四种,可以任意定制,只需要与前后端开发约定一个唯一的标识即可。

如上的例子中,用户管理页面下有用户各种功能,角色管理页面中也有个角色禁用、删除功能,可以分别定义标识为role_disable、role_delete,如果拥有role_delete权限即可,即使没有user_delete权限,也可以直接删除用户,否则就不要给其role_delete权限。

用户登录后,从数据库获取其所拥有的的权限列表并存入vuex,包含页面和功能对应关系,例如页面name为user:{user: [‘user_delete’, ‘user_query’]},页面中根据删除按钮可以v-if="hasPermission(‘user_delete’)"判断即可

页面功能管理:

image.png

获取用户拥有的权限:

image.png

角色

一个角色类似于一个身份或岗位,每个角色有自己的权限范围。

  1. 一个角色可以拥有多个页面权限。

  2. 一个角色可以拥有多个功能权限。

角色管理:

image.png

角色分配权限:

image.png

用户

用户可以创建、删除,一个用户随时可能变更工作内容,或者身兼数职,所以可以为其分配一个或者多个角色,他拥有的角色的权限就是他的权限。此时已经可以打通权限前端的权限分配,用户-角色-页面权限、功能权限。

用户管理:

image.png

用户分配角色:

image.png

前端效果

前端页面菜单效果:

image.png

后端权限

传统前后端不分离的情况下,路由都在后端统一管理,简单的方法比如用户管理页面/user/那么他里面使用的接口都使用/user/add、/user/delete等相同前缀,那么只要判断用户拥有/user/权限就可以访问/user/*所有接口。

前后端分离后面临的问题:

1前、后端分别有自己的路由,且一个页面会同时调后端多个不同模块下的接口,这样一来就无法通过以上传统方式判断权限。

如此一来吗,就需要有前端页面到后端接口的管理,明确一个页面会调用哪几个接口。这样当授权用户页面时,系统就可以根据此关系推断哪些接口具有权限。

接口

方案:

  1. 需要控制权限的接口进行上传管理(可以做成管理页面)

  2. 每个页面和功能可以关联多个接口,比如用户页面关联了用户查询接口和用户编辑接口,用户删除功能关联用户删除接口

  3. 后端对请求的路径进行判断,用户->角色->页面/功能->接口,拥有接口权限即允许访问

  4. 前后端分团队开发,不容易一一对照,且前端有自己的路由(此路由受限于代码组织结构)等等,无法使用传统方式简单处理

  5. 相同的接口可能会被前端多个页面多次利用

接口管理:

image.png

页面关联接口、功能关联接口:

image.png

请求的接口无权限时:

image.png

接口后端权限控制

后端控制其实很简单,只要前面管理功能做好即可,基本逻辑为:

  1. 用户访问接口

  2. 判断用户和当前path,根据用户->角色->页面/功能->接口 得到当前用户有权限的接口列表与当前path相比

  3. 若无权限(某些接口只需要登录就能访问的,比如获取用户姓名信息的需要排除在外)则直接返回失败,前端全局捕获后给出无权限提示

数据库表示例

红色表为实体表,蓝色表为关联关系表。基本为用户->角色->页面/功能->后端接口

在这里插入图片描述

总结

  1. 用户管理

    a.用户增删改查

    b.每个用户分配一个或多个角色

  2. 角色管理

    a.角色增删改查

    b.每个角色分配一个或多个页面、功能授权

  3. 页面管理

    a.页面增删改查

    b.标记页面上下级结构、是否内容页(需对应前端存在的路由页面)、是否可见、是否控制权限等等

    c.前端菜单、面包屑等对用户可感知的内容根据此上下级结构等进行渲染,不必受限于前端代码中的路由

    d.前端路由根据此权限表进行权限控制

  4. 接口权限控制

    a.接口管理录入需要控制权限的接口

    b.将接口分别关联到页面、功能

    c.拥有功能权限则拥有对应接口权限,拥有页面权限则拥有对应的权限

    d.只要通过任意页面和功能拥有接口的权限则可以访问此接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555827.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前后端分离必备的接口规范,十分接地气

1. 前言 随着互联网的高速发展,前端页面的展示、交互体验越来越灵活、炫丽,响应体验也要求越来越高,后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻,从而导致前后端研发各自专注于自己擅长的领域深耕细作。 然…

ubuntu php设置,关于ubuntu php环境设置详解-PHP问题

ubuntu php设置办法:起首更新源列表;而后关上“终端窗口”,输出饬令“sudo apt-get install php5”来装置php;接着装置设置装备摆设好apache环境,并装置php5-gd模块;最初创立“info.php”文件便可。Ubuntu …

MyBatis-Plus——增删查改

开发环境 IDEA JDK:1.8 Spring Boot:2.6.2 Maven:3.3.9 MySQL:8.0.23 数据库准备 CREATE DATABASE mybatis_plus_db;DROP TABLE IF EXISTS person; CREATE TABLE person(id BIGINT(20) NOT NULL COMMENT 主键ID, name VARCHAR(30) NULL DEFAULT NULL COMMENT 姓…

让程序员最爽的ThreadLocal使用姿势

一、常见场景 ​ 1、ThreadLocal作为线程上下文副本,那么一种最常见的使用方式就是用来方法隐式传参,通过提供的set()和get()两个public方法来实现在不同的方法中的参数传递。对于编程规范来说,方法定义的时候是对参数个数是有限制的&#x…

一场事故告诉你zookeeper和nacos谁更适合做注册中心

前言 ​ 在分布式系统中,注册中心充当着重要角色,是服务发现、客户端负载均衡中不可缺少的一员。注册中心除了能够实现基本的功能外,他的稳定性、可用性和健壮性对整个分布式系统的流畅运行影响重大。dubbo作为国内一款主流的分布式系统&…

Mysql执行计划含义,mysql执行计划介绍

烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长。如何写好sql,学会看执行计划至关重要。下面我简单讲讲mysql的执行计划,只列出了一些常见的情况,希望对大家有所帮助。测试表结构&…

寄生虫php版,-PHP版SEO最新教材版排名DeDeCms寄生虫V90繁殖

今天视频教程演示说明下PHP寄生虫服务端的使用。主要在很多搭建的过程中会出错,今天主要就讲解下寄生虫配置常见的问题。那么同样也可以看下我们之前的通用版寄生虫使用教程[通用版教程在文件夹中有],本教程是针对PHP版本的寄生虫服务端进行配置演示。继…

MySQL中 JSON 数据类型应用

前言 今天接触到mysql中json数据类型,之前不知道有这个类型,今天学习一下。 JSON我相信大家都已经很熟悉了,但在 MySQL中,直至 5.7 版本中,才正式引入 JSON数据类型。在次之前,我们通常使varchar或text数…

MySql中json类型的使用___mybatis存取mysql中的json

MySql中json类型的使用 MySQL从5.7.8起开始支持JSON字段,这极大的丰富了MySQL的数据类型。也方便了广大开发人员。但MySQL并没有提供对JSON对象中的字段进行索引的功能,至少没有直接对其字段进行索引的方法。本文将介绍利用MySQL 5.7中的虚拟字段的功能…

百度下拉词+php,百度下拉词是如何生成的?

我们在百度搜索某一词汇的时候,都会在搜索框下面弹出一些相关性和搜索次数比较多的语句或词语,我们在百度上搜索一下,就可以看到用户平时搜索习惯,搜索爱好是什么。护发下拉很多小伙伴就又有疑问了:这些下拉词是根据什…

python元组赋值给变量,Python的赋值

一、序列解包多个赋值操作同时进行:赋值多个值后面再遇到对多个变量赋值时,就不需要对一个变量赋完值再对另一个变量赋值了,用一条语句就可以搞定,例如:再次赋值由输出结果看到,x和y的值交换了,…

微服务,你得知道这

目录 一、业务场景介绍 二、Spring Cloud核心组件:Eureka 三、Spring Cloud核心组件:Feign 四、Spring Cloud核心组件:Ribbon 五、Spring Cloud核心组件:Hystrix 六、Spring Cloud核心组件:Zuul 七、总结 概述…

分布式和微服务的区别

分布式和微服务的区别 1.颜老师,分布式和微服务有什么区别呢?网上说啥的都有,越看越晕了。 答:分布式的核心就一个字:拆。只要是将一个项目拆分成了多个模块,并将这些模块分开部署,那就算是分布…

Oracle数据库空间突然增大,Oracle 表空间异常增长过快解决方法

1. 首先用语句查询容量大于1G的数据段select segment_name,sum(bytes)/1024/1024 from dba_segments group by segment_name having sum(bytes)/1024/1024>1000;得到如下结果:SYS_LOB0000136091C00003$$ 255332MSYS_LOB0000136441C00004$$ 7170MSYS_C…

分布式和微服务是什么?二者的区别又是什么?

一、分布式系统 在《分布式系统原理与范型》一书中有如下定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”; 分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统…

SpringCloud 超详细个人笔记

文章目录SpringCloud1、常见面试题2、微服务概述2.1、什么是微服务2.2、微服务和微服务架构2.3、微服务优缺点2.4、微服务技术栈有哪些?2.5、为什么选择SpringCloud 作为微服务架构2.5.1、选型依据2.5.2、当前各大IT公司用的微服务架构有哪些?2.5.3、各微…

oracle server process,Oracle体系结构及备份(四)server-process

一 什么是服务器进程 除了 Oracle 的后台进程外,还有一些进程是代表用户的,称为服务器进程。这些服务器进程负责按照用户的要求检索数据,并将结果返回给用户。此外,还负责为用户修改缓冲区高数缓存中的数据。 当用户连接到 Oracle…

潘多拉路由器搭建php,MT7620A 无线路由 极路由 1S 定制版 OPERWRT 潘多拉 中继 营销...

定制版 机器 非原版极路由 1S原版极路由下面连接购买https://item.taobao.com/item.htm?id527531952640这个机器是大客户 定制版 营销路由 硬件和极路由 1S 完全相同,只简化了 SD卡座更换为塑胶外壳可以自己DIY 增加USB 接口和SD卡座电源接口为 MICRO USB接口&…

linux close 头文件,Linux open close read write lseek函数的使用

我们经常需要在Linux中进行文件操作,今天我就来分享下文件操作用到的一些函数1 open所需头文件:函数原型:int open(const char *pathname,flags,int perms)pathname:被打开的文件名,可包含路径flag :文件打…

顺序表的实现(头插、尾插、头删、尾删、查找、删除、插入)

目录 一. 数据结构相关概念​ 二、线性表 三、顺序表概念及结构 3.1顺序表一般可以分为: 3.2 接口实现: 四、基本操作实现 4.1顺序表初始化 4.2检查空间,如果满了,进行增容​编辑 4.3顺序表打印 4.4顺序表销毁 4.5顺…