前端权限控制和管理

前端权限控制和管理

  • 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

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

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

相关文章

分布式kettle调度平台- web版转换,作业编排新功能介绍

介绍 Kettle(也称为Pentaho Data Integration)是一款开源的ETL(Extract, Transform, Load)工具,由Pentaho(现为Hitachi Vantara)开发和维护。它提供了一套强大的数据集成和转换功能&#xff0c…

Docker容器访问外网:启动时的网络参数配置指南

在启动Docker镜像时,可以通过设置网络参数来确保容器能够访问外网。以下是几种常见的方法: 1. 使用默认的bridge网络 Docker的默认网络模式是bridge,它会创建一个虚拟网桥,将容器连接到宿主机的网络上。在大多数情况下,使用默认的bridge网络配置即可使容器访问外网。 启动…

大语言模型RAG,transformer

1、RAG技术流总结 第一张图是比较经典的RAG知识图谱,第二张图是更加详细扎实的介绍图。 1.1 索引 坦白来说这部分的技术并不是大模型领域的,更像是之前技术在大模型领域的应用;早在2019年我就做过faiss部分的尝试,彼时索引技术已…

数据结构与算法(test3)

七、查找 1. 看图填空 查找表是由同一类型的数据元素(或记录)构成的集合。例如上图就是一个查找表。 期中(1)是______________. (2)是______________(3)是_____关键字_______。 2. 查找(Searching) 就是根据给定的某个值, 在查…

机器学习在癌症分子亚型分类中的应用

学习笔记:机器学习在癌症分子亚型分类中的应用——Cancer Cell 研究解析 1. 文章基本信息 标题:Classification of non-TCGA cancer samples to TCGA molecular subtypes using machine learning发表期刊:Cancer Cell发表时间:20…

48V电气架构全面科普和解析:下一代智能电动汽车核心驱动

48V电气架构:下一代智能电动汽车核心驱动 随着全球汽车产业迈入电动化、智能化的新时代,传统12V电气系统逐渐暴露出其无法满足现代高功率需求的不足。在此背景下,48V电气架构应运而生,成为现代电动汽车(EV&#xff09…

Mac(m1)本地部署deepseek-R1模型

1. 下载安装ollama 直接下载软件,下载完成之后,安装即可,安装完成之后,命令行中可出现ollama命令 2. 在ollama官网查看需要下载的模型下载命令 1. 在官网查看deepseek对应的模型 2. 选择使用电脑配置的模型 3. copy 对应模型的安…

操作教程丨使用1Panel开源面板快速部署DeepSeek-R1

近期,DeepSeek-R1模型因其在数学推理、代码生成与自然语言推理等方面的优异表现而受到广泛关注。作为能够有效提升生产力的工具,许多个人和企业用户都希望能在本地部署DeepSeek-R1模型。 通过1Panel的应用商店能够简单、快速地在本地部署DeepSeek-R1模型…

免费在腾讯云Cloud Studio部署DeepSeek-R1大模型

2024年2月2日,腾讯云宣布DeepSeek-R1大模型正式支持一键部署至腾讯云HAI(高性能应用服务)。开发者仅需3分钟即可完成部署并调用模型,大幅简化了传统部署流程中买卡、装驱动、配网络、配存储、装环境、装框架、下载模型等繁琐步骤。…

C语言-结构体

1.共用体: union //联合--共用体 早期的时候,计算机的硬件资源有限, 能不能让多个成员变量 公用同一块空间 //使用方式 类似 结构体 --- 也是构造类型 struct 结构体名 { 成员变量名 }; union 共用体名 { 成员变量名 }; //表示构造了一个共用体…

多头自注意力中的多头作用及相关思考

文章目录 1. num_heads2. pytorch源码演算 1. num_heads 将矩阵的最后一维度进行按照num_heads的方式进行切割矩阵,具体表示如下: 2. pytorch源码演算 pytorch 代码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set…

数据仓库和商务智能:洞察数据,驱动决策

在数据管理的众多领域中,数据仓库和商务智能(BI)是将数据转化为洞察力、支持决策制定的关键环节。它们通过整合、存储和分析数据,帮助组织更好地理解业务运营,预测市场趋势,从而制定出更明智的战略。今天&a…

C++ ——从C到C++

1、C的学习方法 (1)C知识点概念内容比较多,需要反复复习 (2)偏理论,有的内容不理解,可以先背下来,后续可能会理解更深 (3)学好编程要多练习,简…

半导体制造工艺讲解

目录 一、半导体制造工艺的概述 二、单晶硅片的制造 1.单晶硅的制造 2.晶棒的切割、研磨 3.晶棒的切片、倒角和打磨 4.晶圆的检测和清洗 三、晶圆制造 1.氧化与涂胶 2.光刻与显影 3.刻蚀与脱胶 4.掺杂与退火 5.薄膜沉积、金属化和晶圆减薄 6.MOSFET在晶圆表面的形…

Avnet RFSoC基于maltab得5G 毫米波 开发工具箱

使用 MATLAB 连接到 AMD Zynq™ RFSoC 评估板。使用 RF 附加卡执行 OTA 测试。使用 HDL Coder 部署算法 版本要求: 大于 2023b 需要以下支持包之一: 适用于 Xilinx 基于 Zynq 的无线电(R2023b 及更早版本)的通信工具箱支持包适…

第三节 docker基础之---Commit+Dockerfile制作

docker目前镜像的制作两种方法: 1,基于docker Commit制作镜像 2,基于dockerfile制作镜像,Dockerfile 为主流的制作方式 如果不制作镜像删除容器之后则里面配置的文件也随之删除: [rootdocker ~]# docker images 查看…

推荐一个免费的、开源的大数据工程学习教程

在当今信息爆炸的时代,每一个企业都会产生大量的数据,而大数据也已经成为很多企业发展的重要驱动力,然而如何有效得处理和分析这些海量的数据,却是一个非常有挑战的技术。 今天推荐一个免费的数据工程教程,带你系统化…

【文档智能多模态】英伟达ECLAIR-端到端的文档布局提取,并集成阅读顺序方法

笔者在前期一个系列分享了各种文档智能相关的技术方法,可以参考《文档智能系列栏目》,涵盖各种常见方法。 下面直接看看这个端到端的文档智能结构化方法,供参考。 方法 一、架构 ECLAIR 采用了一个较大的视觉编码器(657M 参数…

解锁Netty:Channel更替与HashMap管理的奇妙联动

个人CSDN博客主页: java之路-CSDN博客 ( 期待您的关注 ) 目录 Netty 的 Channel 机制探秘 HashMap 在 Netty 中的角色 创建新 Channel 时的操作步骤 新 Channel 的创建流程 确定老 Channel 的标识 移除老 Channel 的具体方法 从 HashMap 中移除 关闭和回收老…

小白零基础如何搭建CNN

1.卷积层 在PyTorch中针对卷积操作的对象和使用的场景不同,如有1维卷积、2维卷积、 3维卷积与转置卷积(可以简单理解为卷积操作的逆操作),但它们的使用方法比较相似,都可以从torch.nn模块中调用,需要调用的…