前端权限控制和管理
前端权限控制和管理
- 1.前言
- 2.权限相关概念
- 2.1权限的分类
- (1)后端权限
- (2)前端权限
- 2.2前端权限的意义
- 3.前端权限控制思路
- 3.1菜单的权限控制
- 3.2界面的权限控制
- 3.3按钮的权限控制
- 3.4接口的权限控制
- 4.实现步骤
- 4.1菜单栏控制
- 4.2界面的控制
- (1)路由导航守卫
- (2)动态路由
- 4.3按钮的控制
- 4.4接口的控制
- (1)请求控制
- (2)响应控制
- 5.小结
- 5.1菜单控制
- 5.2界面控制
- 5.3按钮控制
- 5.4请求和响应控制
1.前言
在Web系统中,一直以来权限都只是后端程序所控制的。因为Web 系统围绕的是数据,而和数据库最紧密接触的是后端程序。所以在很长的一段时间内,权限一直都只是后端程序要考虑的话题。 但是随着前后端分离架构的流行,越来越多的项目也在前端进行权限控制。
2.权限相关概念
2.1权限的分类
(1)后端权限
从根本上讲前端仅仅只是视图层的展示,权限的核心是在于服务器中的数据,所以后端才是权限的关键,后端权限可以控制某个用户是否能够查询数据,是否能够修改数据等操作。
ps:后端如何知道该请求是哪个用户发过来的
- cookie
- session
- token
ps:后端的权限设计RBAC(一般五张表)
- 用户
- 角色
- 权限
- 还有两张关系表
(2)前端权限
本质上来说,前端权限的控制就是控制前端的视图层的展示和前端所发送的请求。但是只有前端权限控制没有后端权限控制是万万不可的。 前端权限控制只是达到锦上添花的效果。
2.2前端权限的意义
如果仅从能够修改服务器中数据库中的数据层面上讲,确实只在后端做控制就足够了,那为什么越来越多的项目也进行了前端权限的控制,主要有这几方面的好处。
- 降低非法操作的可能性;
- 不怕赃偷就怕贼惦记,在页面中展示出一个就算点击了也最终会失败的按钮,势必会增加有心者非法操作的可能性;
- 尽可能排除不必要清求,减轻服务器压力,没必要的请求,操作失败的清求,不具备权限的清求,这些应该压根就不需要发送,请求少了,自然也会减轻服务器的压力;
- 提高用户体验;
- 根据用户具备的权限为该用户展现自己权限范围内的内容,避免在界面上给用户带来困扰,让用户专注于分内之事;
3.前端权限控制思路
3.1菜单的权限控制
在登录请求中,会得到用户的权限数据,当然,这个需要后端返回数据的支持。前端根据权限数据,展示对应的菜单。点击菜单,才能查看相关的界面。
3.2界面的权限控制
如果用户没有登录,手动在地址栏敲入登录后主界面的地址,则需要跳转到登录界面。
如果用户已经登录,如果手动敲入非权限内的地址,则需要跳转404 界面。
3.3按钮的权限控制
在某个菜单的界面中,还得根据权限数据,展示出可进行操作的按钮,比如删除、修改、增加等按钮。
3.4接口的权限控制
如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成启用状态,此时发的请求也应该被前端所拦截。
4.实现步骤
4.1菜单栏控制
用户登录之后,服务端返回一个数据,这个数据有菜单列表和token
,我们把这个数据放入到vuex
中,然后主页根据vuex
中的数据进行菜单列表的渲染。
问题:刷新界面后vuex
数据会消失,菜单栏会消失
解决:将数据存储在sessionStorage
中,并让其和vuex
中的数据保持同步(用专门的持久化插件也可以)
store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)export default new Vuex.Store({state: {//每次点击页面中的刷新按钮,state中的数据就会根据下面的数据重新初始化rightList: JSON.parse(sessionStorage.getItem('rightList') || '[]'),username: sessionStorage.getItem('username'),},mutations: {setRightList(state, newData) {state.rightList = newDatasessionStorage.setItem('rightList', JSON.stringify(newData)) //sessionStorage只能存储字符串},setUsername(state, newData) {state.username = newDatasessionStorage.setItem('username', newData)},},actions: {},getters: {},
})
4.2界面的控制
登录成功后,将token
数据存储在sessionStorage
中,用来判断是否登录
(1)路由导航守卫
router/index.js:
router.beforeEach((to, from, next) => {//页面跳转之前做拦截动作,判断token是否存在if (to.path === '/login') next()else {const token = sessionStorage.getItem('token')if (!token) next('/login')else {next()}}})
问题:这样用户在登录之后就可以访问其他界面了,但如果用户A登录之后只能访问a页面不能访问b页面,但是这时候他还是可以通过地址栏输入进入到b页面。
解决:当然我们也可以设置路由导航守卫,但是如果有多个页面,设置会非常不方便,并且对于用户A来说,它是不用访问b页面的,这时候我们可以对A不显示b页面,这个时候我们就用到了动态路由。
(2)动态路由
根据当前用户所拥有的的权限数据来动态添加所需要的路由。
先定义好所有的路由规则:
router/routerMap.js:
import Users from '@/components/user/Users.vue'
import Roles from '@/components/role/Roles.vue'
import GoodsCate from '@/components/goods/GoodsCate.vue'
import GoodsList from '@/components/goods/GoodsList.vue'const userRule = { path: '/users', component: Users }
const roleRule = { path: '/roles', component: Roles }
const goodRule = { path: '/goods', component: GoodsList }
const categoryRule = { path: '/categories', component: GoodsCate }const routesMap = {users: userRule,roles: roleRule,goods: goodRule,categories: categoryRule,
}
export { routesMap }
登录成功之后动态添加路由,注意这个initDynamicRoutes
的方法需要暴露出去在登录页面调用
这样当用户A在地址栏输入自己不能访问的路由时,就不会跳转到该页面,而是跳转到404页面。
问题:如果我们重新刷新的话动态路由就会消失,动态路由是在登录成功之后才会调用,刷新的时候并没有调用,所以动态路由没有添加上。
解决:可以在app.vue
中的created中
调用添加动态路由的方法
4.3按钮的控制
虽然用户可以看到某些界面了,但是对于这个界面的一些按钮,该用户可能是没有权限的。 因此,我们需要对组件中的一些按钮进行控制,用户不具备权限的按钮就隐藏或者禁用,而在这块的实现中,可以把该逻辑放到自定义指令中
比如我们可以根据后端返回的数据right来判断用户有什么权限,如下图。
添加自定义指令 控制按钮:
import Vue from 'vue'
import store from '../store';
import router from '../router';
const permission = {inserted(el, binding) {//传过来的参数中,action表示被绑定的按钮是什么操作;effect表示当用户没有这个操作权限的时候,//应该如何如理这个按钮const action = binding.value.actionconst effect = binding.value.effect//获取用户在当前路由中所具有的权限列表let currentPathPermissions = router.currentRoute.meta if(currentPathPermissions.indexOf(action) == -1){if(effect === 'disabled'){el.disabled = trueel.classList.add('is-disabled') //element-ui需要的处理}elseel.parentNode.removeChild(el)//el.style.display = 'none'}}
}
Vue.directive('permission', permission)
4.4接口的控制
(1)请求控制
除了登录请求都得要带上token,这样服务器才可以鉴别你的身份。这块需要配置axios的请求拦截器。
如果发出了非权限内的请求,应该直接在前端范围内阻止,虽然这个请求发到服务器也会被拒绝。
非权限内的请求:比如a用户是不能够操作该页面的按钮的,但是他通过f12调试把按钮改为可点击,如果我们不对这个请求进行处理,那么这个请求就会发送出去。
//当前模块中具备的权限关系映射
const actionMapping = {get: 'view', //查看-->get请求post: 'add', //添加-->post请求put: 'edit', //编辑-->put请求delete: 'delete', //删除-->delete请求
}
//请求拦截控制
axios.interceptors.request.use((request) => {// console.log(request.url);// console.log(request.method);if (request.url !== 'login') {//除了登录请求以外,在请求头中全部添加上tokenrequest.headers.Authorization = sessionStorage.getItem('token')//将请求方式映射成为操作类型的权限const action = actionMapping[request.method]//获取用户在当前路由下所具有的权限const currentRight = router.currentRoute.metaif (currentRight && currentRight.indexOf(action) === -1) {//没有权限发送请求,通过报错拦截alert('没有权限!')return Promise.reject(new Error('没有权限'))}}return request
})
(2)响应控制
得到了服务器返回的状态码401,代表token 超时或者被篡改了,此时应该强制跳转到登录界面。
axios.interceptors.response.use((response) => {if (response.data.meta.status === 401) {//返回401表示token失效,返回登陆界面router.push('/login')sessionStorage.clear()window.location.reload()}return response
})
5.小结
- 前端权限的实现必须要后端提供数据支持,否则无法实现。
- 返回的权限数据的结构,前后端需要沟通协商怎样的数据用起来才最方便。
5.1菜单控制
- 权限的数据需要在多组件之间共享,因此采用
vuex
。 - 防止刷新界面权限数据丢失,所以需要使用
sessionStorage
进行持久化,并目要保证两者的同步。
5.2界面控制
- 路由的导航守卫可以防止跳过登录界面。
- 动态路由可以让不具备权限的界面的路由规则压根就不存在。
5.3按钮控制
- 路由规则中可以增加路由元数据meta。
- 通过路由对象可以得到当前的路由规则以及存在此规则中的meta数据。
- 自定义指令可以很方便的实现按钮控制。
5.4请求和响应控制
- 请求拦截器和响应拦截器的使用。
- 请求方式的约定
restful
。
相关文章:

前端权限控制和管理
前端权限控制和管理 1.前言2.权限相关概念2.1权限的分类(1)后端权限(2)前端权限 2.2前端权限的意义 3.前端权限控制思路3.1菜单的权限控制3.2界面的权限控制3.3按钮的权限控制3.4接口的权限控制 4.实现步骤4.1菜单栏控制4.2界面的控制(1)路由导航守卫(2)动态路由 4.3按钮的控制…...
网络安全讲座之一:网络安全的重要性
第一讲内容主要对于安全的发展以及其重要性作了简明的阐述,并介绍了一些国内外知名的网络安全相关网站,并对于如何建立有效的安全策略给出了很好的建议,并让大家了解几种安全标准。 媒体经常报道一些有关网络安全威胁的令人震惊的事件&am…...
iOS主要知识点梳理回顾-3-运行时消息机制
运行时(runtime) 运行时是OC的重要特性,也是OC动态性的根本支撑。动态,如果利用好了,扩展性就很强。当然了,OC的动态性只能算是一个一般水平。与swift、java这种强类型校验的语言相比,OC动态性很…...

深度学习中的Checkpoint是什么?
诸神缄默不语-个人CSDN博文目录 文章目录 引言1. 什么是Checkpoint?2. 为什么需要Checkpoint?3. 如何使用Checkpoint?3.1 TensorFlow 中的 Checkpoint3.2 PyTorch 中的 Checkpoint3.3 transformers中的Checkpoint 4. 在 NLP 任务中的应用5. 总…...

STM32开发笔记,编译与烧录
1. Keil开发环境 【Project】》【Manager】》【Pack Installer】选择相应的芯片,Unpack安装。 2. 编译 3. 烧录 烧录时,Boot0 为 1,Boot1 为 0。烧录后启动,Boot0 为 0 ,Boot 1 为 0。 3.1 ST-LINK烧录 测试连接&a…...
【CXX-Qt】1 CXX-Qt入门
与其他Qt-Rust绑定相比,CXX-Qt的目标不仅仅是将Qt功能暴露给Rust,而是完全将Rust集成到Qt生态系统中。我们将通过一个最小示例,展示如何使用CXX-Qt在Rust中创建自己的QObject,并将其与基于QML的小型GUI集成。 一、阅读前准备知识…...

JS宏进阶:XMLHttpRequest对象
一、概述 XMLHttpRequest简称XHR,它是一个可以在JavaScript中使用的对象,用于在后台与服务器交换数据,实现页面的局部更新,而无需重新加载整个页面,也是Ajax(Asynchronous JavaScript and XML)…...

物联网智能语音控制灯光系统设计与实现
背景 随着物联网技术的蓬勃发展,智能家居逐渐成为现代生活的一部分。在众多智能家居应用中,智能灯光控制系统尤为重要。通过语音控制和自动调节灯光,用户可以更便捷地操作家中的照明设备,提高生活的舒适度与便利性。本文将介绍一…...
hyperf知识问题汇总
1、简单说下 hyperf(什么是 hyperf) 答:hyperf 是一个依赖swoole扩展的 php 开源开发框架,它由黄朝辉团队设计创建维护,具备简洁而强大的组件和超强的并发性能,而且还支持微服务架构,例如&…...

制药行业 BI 可视化数据分析方案
一、行业背景 随着医药行业数字化转型的深入,企业积累了海量的数据,包括销售数据、生产数据、研发数据、市场数据等。如何利用这些数据,挖掘其价值,为企业决策提供支持,成为医药企业面临的重大挑战。在当今竞争激烈的…...

【SVN基础】
软件:ToritoiseSVN 代码版本回退:回退到上一个版本 问题:SVN版本已经提交了版本1和版本2,现在发现不需要版本2的内容,需要回退到版本1然后继续开发。 如图SVN版本已经提交到了107版本,那么本地仓库也已经…...

多项式插值(数值计算方法)Matlab实现
多项式插值(数值计算方法)Matlab实现 一. 原理介绍二. 程序设计1. 构建矩阵2. 求解矩阵方程3. 作出多项式函数4. 绘制插值曲线5. 完整代码 三. 图例 一. 原理介绍 关于插值的定义及基本原理可以参照如下索引 插值原理(数值计算方法ÿ…...

[AI]Mac本地部署Deepseek R1模型 — — 保姆级教程
[AI]Mac本地部署DeepSeek R1模型 — — 保姆级教程 DeepSeek R1是中国AI初创公司深度求索(DeepSeek)推出大模型DeepSeek-R1。 作为一款开源模型,R1在数学、代码、自然语言推理等任务上的性能能够比肩OpenAI o1模型正式版,并采用MI…...

android手机本地部署deepseek1.5B
手机本地部署大模型需要一个开源软件 Release Release v1.6.7 a-ghorbani/pocketpal-ai GitHub 下载release版本apk 它也支持ios,并且是开源的,你可以编译修改它 安装完后是这样的 可以下载推荐的模型,也可以在pc上下载好,然后copy到手机里 点 + 号加载本地模型...
理解UML中的四种关系:依赖、关联、泛化和实现
在软件工程中,统一建模语言(UML)是一种广泛使用的工具,用于可视化、设计、构造和文档化软件系统。UML提供了多种图表类型,如类图、用例图、序列图等,帮助开发者和设计师更好地理解系统的结构和行为。在UML中…...

机器学习 - 词袋模型(Bag of Words)实现文本情感分类的详细示例
为了简单直观的理解模型训练,我这里搜集了两个简单的实现文本情感分类的例子,第一个例子基于朴素贝叶斯分类器,第二个例子基于逻辑回归,通过这两个例子,掌握词袋模型(Bag of Words)实现文本情感…...

Kimi k1.5: Scaling Reinforcement Learning with LLMs
TL;DR 2025 年 kimi 发表的 k1.5 模型技术报告,和 DeepSeek R1 同一天发布,虽然精度上和 R1 有微小差距,但是文章提出的 RL 路线也有很强的参考意义 Paper name Kimi k1.5: Scaling Reinforcement Learning with LLMs Paper Reading Note…...

如何评估云原生GenAI应用开发中的安全风险(下)
以上就是如何评估云原生GenAI应用开发中的安全风险系列中的上篇内容,在本篇中我们介绍了在云原生AI应用开发中不同层级的风险,并了解了如何定义AI系统的风险。在本系列下篇中我们会继续探索我们为我们的云原生AI应用评估风险的背景和意义,并且…...
ASP.NET Core程序的部署
发布 不能直接把bin/Debug部署到生产环境的服务器上,性能低。应该创建网站的发布版,用【发布】功能。两种部署模式:“框架依赖”和“独立”。独立模式选择目标操作系统和CPU类型。Windows、Linux、iOS;关于龙芯。 网站的运行 在…...
《深度LSTM vs 普通LSTM:训练与效果的深度剖析》
在深度学习领域,长短期记忆网络(LSTM)以其出色的处理序列数据能力而备受瞩目。而深度LSTM作为LSTM的扩展形式,与普通LSTM在训练和效果上存在着一些显著的不同。 训练方面 参数数量与计算量:普通LSTM通常只有一层或较少…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...