前后端分离如何做权限控制设计?

简介: 近几年随着react、angular、vue等前端框架兴起,前后端分离的架构迅速流行。但同时权限控制也带来了问题。网上很多前、后端分离权限仅仅都仅仅在描述前端权限控制、且是较简单、固定的角色场景,满足不了我们用户、角色都是动态的场景。且仅仅前端进行权限控制并不是真正意义的权限控制,它只是减少页面结构暴露、增强用户体验的功效。

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


网上很多前、后端分离权限仅仅都仅仅在描述前端权限控制、且是较简单、固定的角色场景,满足不了我们用户、角色都是动态的场景。


且仅仅前端进行权限控制并不是真正意义的权限控制,它只是减少页面结构暴露、增强用户体验的功效。


场景

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


为什么不行:


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


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


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


页面

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


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


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


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


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


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


菜单和页面组成上下级关系,一级可以是菜单也可以是内容页,内容页也可以放在菜单下,这样理论(需要页面菜单样式支持)可以组成无限级菜单


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


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


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


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


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


页面管理:


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')"判断即可。


关注微信公众号:Java技术栈,在后台回复:架构,可以获取我整理的 N 篇最新架构教程,都是干货。


页面功能管理:


image.png


获取用户拥有的权限:


image.png


角色

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


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


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


角色管理:


image.png


角色分配权限:


image.png


用户

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


用户管理:


image.png


用户分配角色:


image.png


前端效果

前端页面菜单效果:


image.png


后端权限

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


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


接口

方案:


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


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


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


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


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


相关文章
|
6月前
|
文字识别 Python
python做ocr卡证识别很简单
本示例展示了如何使用 `potencent` 库调用腾讯云 OCR 服务识别银行卡和身份证信息。代码中分别通过本地图片路径 (`img_path`) 和配置文件 (`potencent-config.toml`) 实现了银行卡和身份证的 OCR 识别,并输出结果。测试图片及结果显示了识别效果,需提前配置腾讯云的 `SECRET_ID` 和 `SECRET_KEY`。
|
缓存 资源调度 JavaScript
Vue集成Excalidraw实现在线画板功能
Excalidraw是一款开源在线绘图工具,适用于白板、思维导图、原型设计等场景。支持手绘风格、多种图形元素、导出功能及多人协作,深受开发者喜爱。本文档介绍了如何在Vue项目中集成Excalidraw,包括安装依赖、配置文件修改、页面添加等步骤,帮助开发者快速上手。
1776 0
Vue集成Excalidraw实现在线画板功能
|
11月前
|
前端开发 JavaScript API
提取网页所有链接免费API接口教程
此API用于提取指定网页内的所有链接信息并进行分类,支持POST和GET请求方式。需提供用户ID、KEY及目标网址等参数,可选指定访问节点。返回结果包括状态码、信息提示及各类链接集合,如图片、视频、文档等。示例中展示了请求格式与返回数据结构。
|
人工智能 自然语言处理 PHP
通义灵码体验评测
通义灵码体验评测
501 2
|
存储 前端开发 JavaScript
若依权限系统分析(前后端分离版)
若依权限系统分析(前后端分离版)
1322 1
|
运维 Devops 测试技术
DevOps实践:自动化部署与持续集成
【8月更文挑战第24天】在软件工程的世界里,DevOps已经成为一种提升效率和质量的必由之路。本文将深入探讨如何通过自动化部署和持续集成来实施DevOps策略。我们将从基础概念出发,逐步引导读者理解并实现一个简单而强大的自动化部署流程,同时展示如何利用持续集成来保障代码质量和快速迭代。文章旨在为读者提供清晰的操作指南和思路启发,帮助团队构建更加高效、稳定和可靠的软件开发与运维环境。
|
自然语言处理 JavaScript 前端开发
VuePress与Docusaurus:构建高效文档站点
VuePress和Docusaurus是用于构建技术文档的静态站点生成器。VuePress基于Vue.js,适合Vue开发者,提供Markdown增强和即时预览;Docusaurus使用React,有内置多语言支持和版本管理。两者都有活跃社区,VuePress适合深度定制,Docusaurus注重开箱即用。选择取决于技术栈和需求。
290 1
|
存储 前端开发 JavaScript
前端菜单及按钮权限拦截,实现方案及思路
此实现方案基于vue框架,并需要依赖vue项目相关的库,router、store等等;前端同学要与后端同学协商,常规是让后端返回一个树结构的菜单数据,并且将所有的涉及权限控制的页面path给到后端,如果是按钮,需要把所有的按钮 code 码统一下,这是前期工作,很重要。
|
缓存 前端开发 JavaScript
前端vue3分享——项目封装axios、vite使用env环境变量
前端vue3分享——项目封装axios、vite使用env环境变量
1664 0
|
自然语言处理 文字识别 数据可视化
从PDF和图像中提取文本,以供大型语言模型使用
从PDF和图像中提取文本,以供大型语言模型使用