权限管理实现的两种方式(详解)
登录的接口请求的三个内容:
1. token
2. 用户信息、角色信息
3. 菜单信息
第一种:基于角色Role的动态路由管理 (不推荐,但市场用的比较多)
首先列出枚举每个角色对应几个路由,然后根据用户登录的角色遍历枚举出来的角色动态注册对应的路由
const roles = {admin:['所有路由'],'经理':['10个路由'],'运营':['5个路由'],'前台':['2个路由']'新增一个角色':[xxx] ===>改代码重新发布版本
}这种做法一个弊端:每添加一个角色,都要手动添加代码key:value。最后前端又要发布新的版本(有解决方案如下)
这种方法大致流程如下:
登录:登录验证通过之后后台会返回一个token给前端,前端会保存在vuex和本地(防止刷新丢失登录状态),然后拿token去后台请求一个userInfo的接口获取用户信息(用户名,权限信息等等)
权限验证:通过token获取用户role信息,然后根据用户role算出对应应有权限信息的路由,最后用router.addRotes动态挂载计算出的路由。
代码的实现:
根据token拿到用户信息(权限信息)
这里代码过于简单就不写了,就是请求后台的数据而已。

请求回来的数据保存在Vuex当中(actions发请求----mutations传数据给state,过程不书写了)
//箭头函数
const getDefaultState = () => {return {//获取tokentoken: getToken(),//存储用户名name: '',//存储用户头像avatar: '',//服务器返回的菜单信息【根据不同的角色:返回的标记信息,数组里面的元素是字符串】routes: [],//角色信息roles: [],//按钮权限的信息buttons: [],}
}vuex查看数据:保存成功

Router中路由的拆分(现在路由是全部注册好的,写死的,不管什么用户看的都是一样的页面。)
分为三类路由:
常量路由,不管什么角色都可以看得路由
任意路由:路径出错的时候重定向404
异步路由:不同角色需要过滤选出路由(根据后台的返回的角色计算出对呀的路由)

store/user.js中对比路由
首先要在state定一个计算好的路由变量resultAsyncRoutes:[] 和一个最终合并展示路由变量resultAllRputes:[]

在获取用户信息的时候异步路由和服务器返回的路由进行对比。commit要提交对比好的路由,所有写一个对比路由函数。computedAsyncRoutes()函数第一个参数是异步路由,第二个是服务器返回的路由。
在actions外面定义一个对比路由的computedAsyncRoutes函数:
//定义一个函数:两个数组进行对比,对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (asyncRoutes, routes) => {//过滤出当前用户【超级管理|普通员工】需要展示的异步路由return asyncRoutes.filter(item => {//数组当中没有这个元素返回索引值-1,如果有这个元素返回的索引值一定不是-1 if (routes.indexOf(item.name) != -1) {//递归:别忘记还有2、3、4、5、6级路由if (item.children && item.children.length) {item.children = computedAsyncRoutes(item.children, routes);}return true;}})
}commit的时候对比好路由(需要深拷贝一下,不然对比后数据影响原数据)

打印异步路由和服务器返回的路由:

然后在mutations中合并路由(计算出来的异步路由,常量路由,任意路由进行合并)用router.addRotes动态挂载计算出的路由。

根据计算出路由展示菜单
目前为止路由都准备好了,但是侧边栏展示还是常量路由,侧边栏应该遍历vuex合并好的路由resultAllRputes
在Sidebar组件中:

这样侧边栏就这根据权限动态展示了。
按钮权限:
菜单权限:不同的用户(角色),能操作、能观看的菜单是不同的。
按钮的权限:不同的用户(角色),有的用户的是可见按钮、当然有的用户不可见。
实现方式也比较简单:根据后台返回button是否有这个按钮的权限值。

用v-if去判断后台返回buttons是否包含该按钮的权限,没有就不显示。
<template><div><el-button type="primary" v-if="$store.state.user.buttons.indexOf('btn.Add1')!=-1">添加按钮1</el-button><el-button type="primary" v-if="$store.state.user.buttons.indexOf('btn.Add2')!=-1">添加按钮2</el-button></div>
</template>第二种:基于菜单Menu的动态路由管理(推荐)
我这里是从0搭建的,很多细节需要自己处理,看起来比上面的方法麻烦其实不是这样的,上面是使用vue-admin很多细节作者已经处理好了,我这里需要自己处理,也更好的理解各种细节问题。
userMenus =>动态展示菜单
用户管理 ----商品管理----角色管理等等这些路由模块映射成一个对象然后和后端返回这个角色的菜单信息进行对比,然后用Router.addRotes的API动态注册路由。
大致流程:(Vue3+TS+pinia实现)
这里的后台和上面的返回格式不一样,问题也不大。首页还是拿到token,用token拿用户信息,用户信息中有用户id,那个用户id去后台拿菜单信息。

后台返回的菜单信息:

然后对路由进行划分:

对比一下他们的路由信息:

然后进行路由对比,对比好就动态注册路由,要点击登录前就要计算好路由,也就是说push到首页就要算好路由,所有在login中actions进行对比,但是这个逻辑比较多,为了方便管理对比路由函数写在utils
在utils中:
这里用了两个for循环因为这里明确知道两次目录,要是children两层以上可以用递归

在login中actions使用:
计算好的路由放到routes数组中,然后forEach遍历用router.addRoute动态添加路由(addRoute第一个参数是目标路由,第二个参数就是路由信息,代码上的意思就是将遍历出来的路由信息添加main的children下面)

目前效果可以做到点击菜单路由也可以跟着改变了

但是目前有一个问题就是,我注册权限路由是pinia的actions在点击登录按钮的回调进行注册的,现在当我刷新的时候这些路由就访问不到了,只能访问不用权限的路由,为什么会这样?
因为刷新不会重新加载pinia的actions的登录的回调,只有点击登录才会执行,解决办法就是刷新让这个回调重新执行一遍。具体实现如下:
在actions在定一个函数

函数定义好了,要让他刷新执行一遍,需要在main执行(顺序比较重要批念必须先加载,然后再动态注册权限路由,最后加载router)

第一个页面的匹配方法:
现在做一个小细活,就是登录完立刻重定向到第一个页面(这个需要动态的,不是每个角色第一个页面都是一样的)
在那个utils中的mapMenusToRouters函数增加两句代码

然后再router里面的前置守卫使用

根据path匹配menu
现在点击部门管理刷新会跳转到一点页面,我们要的还是留在部门管理这个路由

在nav-menu组件组件中:

计算出defaultActive

在utils写工具函数

大致流程就是这样了。
文章有帮助到您帮忙点个赞赞~~~
相关文章:
权限管理实现的两种方式(详解)
登录的接口请求的三个内容:1. token2. 用户信息、角色信息3. 菜单信息第一种:基于角色Role的动态路由管理 (不推荐,但市场用的比较多)首先列出枚举每个角色对应几个路由,然后根据用户登录的角色遍历枚举出来的角色动态注册对应的路…...
【C++】智能指针思路解析和模拟实现
此篇文章就从以下几个方面出发,带你了解智能指针的方方面面1.为什么需要智能指针当我们开辟内存并使用的时候,我们的顺序应该是这样:开辟内存-》使用内存-》释放内存问题就出现在第三步,开辟好了,也使用了,…...
SpringCloud(18):Sentinel流控降级入门
Sentinel本地应用流控降级实现分为三步: 创建本地应用搭建本地Sentinel控制台本地应用接入本地Sentinel控制台1 本地应用创建 整体流程分析 创建springboot项目在项目的pom.xml文件中引入sentinel-core的依赖坐标创建TestController,定义使用限流规则运行测试具体流程 1.创…...
C++【多态】
文章目录1、多态的概念2、多态的定义及实现2-1、多态的构成条件2-2、虚函数2-3、虚函数的重写2-4 多态样例2-5、协变2-6、 析构函数与virtual2-7、函数重载、函数隐藏(重定义)与虚函数重写(覆盖)的对比2-8、override 和 final&…...
缓存预热、缓存雪崩、缓存击穿、缓存穿透,你真的了解吗?
缓存穿透、缓存击穿、缓存雪崩有什么区别,该如何解决? 1.缓存预热 1.1 问题描述 请求数量较高,大量的请求过来之后都需要去从缓存中获取数据,但是缓存中又没有,此时从数据库中查找数据然后将数据再存入缓存…...
【Java基础】018 -- 面向对象阶段项目上(拼图小游戏)
目录 拼图小游戏(GUI) 一、主界面分析 1、练习一:创建主界面1 2、练习二:创建主界面2(JFrame) 3、练习三:在游戏界面中添加菜单(JMenuBar) ①、菜单的制作 4、添加图片&a…...
【网络~】
网络一级目录二、socket套接字三、UDP数据报套接字四、TCP流套接字一级目录 1.局域网、广域网 2.IP地址是什么? IP地址是标识主机在网络上的地址 IP地址是如何组成的? 点分十进制,将32位分为四个部分,每个部分一个字节ÿ…...
手写JavaScript中的call、bind、apply方法
手写JavaScript中的call、bind、apply方法 call方法 call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。 function Product(name, price) {this.name name;this.price price; }function Food(name, price) {Product.call(this, name, price);t…...
JAVA练习46-将有序数组转换为二叉搜索树
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 2月10日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-…...
linux(centos7.6)docker
官方文档:https://docs.docker.com/engine/install/centos/1安装之前删除旧版本的docker2安装yum install-y yum-utils3配置yum源 不用官网的外国下载太慢 推荐阿里云yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.r…...
微信小程序滚动穿透问题
文章目录1、catchtouchmove"true"2、page-meta3、wx.setPageStyle做小程序的开发业务中,经常会使用弹窗,当弹窗里的内容过多时,要滚动查看,然后经常会遇到滚动弹窗,弹窗底下页面也跟着滚。解决思路ÿ…...
安全—06day
负载均衡反向代理下的webshell上传负载均衡负载均衡下webshell上传的四大难点难点一:需要在每一台节点的相同位置上传相同内容的webshell难点二:无法预测下一次请求是哪一台机器去执行难点三:当我们需要上传一些工具时,麻烦来了&a…...
PostgreSQL入门
PostgreSQL入门 简介 PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS) 支持大部分SQL标准并且提供了许多现代特性 复杂查询外键触发器可更新视图事务完整性多版本并发控制 …...
自媒体人都在用的免费音效素材网站
视频剪辑、自媒体人必备的剪辑音效素材网站,免费下载,建议收藏! 1、菜鸟图库 音效素材下载_mp3音效大全 - 菜鸟图库 菜鸟图库是一个综合性素材网站,站内涵盖设计、图片、办公、视频、音效等素材。其中音效素材就有上千首…...
Java数据结构中二叉树的深度解析及常见OJ题
本篇文章讲述Java数据结构中关于二叉树相关知识及常见的二叉树OJ题做法讲解(包含非递归遍历二叉树) 目录 一、二叉树 1.1二叉树概念 1.2特殊的二叉树 1.3二叉树性质 1.4二叉树基本性质定理题 1.5二叉树遍历基本操作 1.6二叉树遍历的前中后非递归写法 1.7…...
算法顶级比赛汇总
可参赛的算法比赛 阿里云天池大数据竞赛 时间:每年各个季度很多类型都会出题(比赛总时间大概为两个月) 内容:各个类型的算法题都会出、奖金上万不等 形式:在线提交(提交后在线检查结果)、离线…...
Android MVI框架搭建与使用
MVI框架搭建与使用前言正文一、创建项目① 配置AndroidManifest.xml② 配置app的build.gradle二、网络请求① 生成数据类② 接口类③ 网络请求工具类三、意图与状态① 创建意图② 创建状态四、ViewModel① 创建存储库② 创建ViewModel③ 创建ViewModel工厂五、UI① 列表适配器②…...
第九节 使用设备树实现RGB 灯驱动
通过上一小节的学习,我们已经能够编写简单的设备树节点,并且使用常用的of 函数从设备树中获取我们想要的节点资源。这一小节我们带领大家使用设备树编写一个简单的RGB 灯驱动程序,加深对设备树的理解。 实验说明 本节实验使用到STM32MP1 开…...
Ubuntu 系统下Docker安装与使用
Ubuntu 系统下Docker安装与使用Docker安装与使用Docker安装安装环境准备工作系统要求卸载旧版本Ubuntu 14.04 可选内核模块Ubuntu 16.04 使用 APT 安装安装 Docker CE使用脚本自动安装启动 Docker CE建立 docker 用户组测试 Docker 是否安装正确镜像加速Docker使用拉取镜像创建…...
DHCP安全及防范
DHCP安全及防范DHCP面临的威胁DHCP饿死攻击仿冒DHCP Server攻击DHCP中间人攻击DHCP Snooping技术的出现DHCP Snooping防饿死攻击DHCP Snooping防止仿冒DHCP Server攻击DHCP Snooping防止中间人攻击DHCP Snooping防止仿冒DHCP报文攻击DHCP面临的威胁 网络攻击无处不在ÿ…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
