权限控制权限控制权限控制权限控制权限控制

1.权限的分类

视频学习:https://www.bilibili.com/video/BV15Q4y1K79c/?spm_id_from=333.337.search-card.all.click&vd_source=386b4f5aae076490e1ad9b863a467f37

1.1 后端权限

1. 后端如何知道该请求是哪个用户发过来的

可以根据 cookiesessiontoken,一般是根据token获取的

2. 后端的权限设计RBAC

权限一般是分配给角色角色下有很多用户,这样用户就有对应的权限
一个用户可以有多个角色,一个角色下有很多用户

1.2 前端权限

1.必要性

前端权限的控制本质上来说, 就是控制端的视图层的展示和前端所发送的请求。但是只有前端权限控制没有后端权限控制是万万不可的。 前端权限控制只可以说是达到锦上添花的效果。

2.好处

为什么越来越多的项目也进行了前端权限的控制, 主要有这几方面的好处:

  1. 降低非法操作的可能性,无权限的按钮可能会带来有心者非法操作
  2. 尽可能排除不必要清求, 减轻服务器压力
  3. 提高用户体验,避免在界面上给用户带来困扰, 让用户专注于分内之事

2.前端权限控制思路

2.1 菜单的控制

根据后端返回的数据. 前端展示对应的菜单. 点击菜单, 才能查看相关的界面

2.2 界面的控制

如果用户没有登录, 手动在地址栏敲入管理界面的地址, 则需要跳转到登录界面
如果用户已经登录, 如果手动敲入非权限内的地址, 则需要跳转404 界面

2.3 按钮的控制

在某个菜单的界面中, 还得根据权限数据, 展示出可进行操作的按钮,比如删除, 修改, 增加

2.4 请求和响应的控制

如果用户通过非常规操作, 比如通过浏览器调试工具将某些禁用的按钮变成启用状态, 此时发的请求, 也应该被前端所拦截

3.实现步骤

3.1 权限菜单栏控制

3.1.1 登录按钮

  1. 点击登录按钮 ,获取token和侧边栏数据,将侧边栏数据存入vuex中
  2. 在home组件中获取侧边栏数据,渲染到侧边栏

出现的问题:刷新浏览器,vuex的数据会被清空
解决:与sessionStorage结合使用

store文件下的index.js

import Vue from 'vue
import Vuex from 'vuex
Vue .use(Vuex)export default new Vuex.store({state:{rightlist:JsoN.parse(sessionstorage.getItem('rightList')||'[]')},mutations:{setRightList(state, data){state.rightList = datasessionStorage.setItem('rightList',JSON.stringify(data))},...

login.vue的代码:

login(){this.$refs.loginFormRef.validate(async valid =>{...this.$store.commit('setRightList', res.rights)this.$message.success('登录成功')this.$router .push('/home')})}

home.vue的代码:

import{mapstate }from 'vuex'
computed:{...mapstate(['rightList'])
}
created(){this.activePath =window.sessionstorage.getItem('activePath')this.menulist = this.rightList
}

3.1.2 登出按钮

期望:退出后,清空sessionStorage缓存和vuex的数据

logout(){// 删除sessionstorage中的数据sessionStorage.clear()this.$router.push("/login')// 删除vuex中的数据,让当前的界面刷新window.location.reload()
}

3.2 界面的控制

3.2.1 登录成功之后才能跳转到管理平台界面。

但是如果用户直接敲入管理平台的地址,也是可以跳过登录的步骤,所以应该在某个时机判断用户是否登录
1)如何判断是否登录
缓存中是否有token

sessionStorage.setItem('token', res.data.token)

2)什么时候判断
路由导航守卫

router.beforeEach((to,from,next)=>{if(to.path ==='/login'){next()} else {const token =sessionstorage.getItem('token')if(!token){next('/login')} else {next()}}
})

3.2.2 具备菜单权限才能跳转到访问页面

虽然菜单项已经被控制住了,但是路由信息还是完整的存在于浏览器,正比如zhangsan这个用户并不具备角色这个菜单,但是他如果自己在地址栏中敲入/roles的地址,依然也可以访问角色界面
路由导航守卫固然可以在每次路由地址发生变化的时候,从vuex中取出rightlist判断用户将要访问的界面,这个用户到底有没有权限。不过从另外一个角度来说,这个用户不具备权限的路由,是否也应该压根就不存在呢?
router.js

import Vue from "vue
import Router from 'yue-router
import Login from '@/components/Login.vue'
import Home from'@/components/Home.vue'
import welcome from '@/components/welcome.vue'
import Users from'@/components/user/Users.vue'
import Roles from'@/components/role/Roles.vue'
import GoodsCate from '@/components/goods/GoodsCate.vue'
importGoodsList from '@/components/goods/GoodsList.vue'
import NotFound from '@/components/NotFound.vue'
import store from '@/store1mport'Vue.use(Router)const userRule={path:/users',component:Users }
const roleRule ={path:'/roles', component: Roles }
const goodsRule={path:'/goods', component: GoodsList }
const categoryRule ={ path:"/categories', component: Goodscate }const ruleMapping ={
'users': userRule,
'roles': roleRule,
'goods': goodsRule,
'categories': categoryRule
}const router = new Router({routes:[{path:'/'redirect:'/home',},{path:'/1ogin',component: Login,},{path:'/home',component:Home,redirect:"/welcomechildren:[{ path:'/welcome',component:welcome },//{path:'/users',component:Users },// { path: '/roles',component:Roles },//{ path:'/goods',component:GoodsList },//{path:"/categories',component: GoodsCate }}},{path:'*',component: NotFound}
]
}]router.beforeEach((to,from,next)=>{if(to.path ==='/login'){next()} else {const token =sessionstorage.getItem('token')if(!token){next('/login')} else {next()}}
})export function initDynamicRoutes(){//根据二级权限,对路由规则进行动态的添加const currentRoutes =router.options.routesconst rightList =store.state.rightListrightList.forEach(item =>{item.children.forEach(item =>{//item 二级权限const temp = ruleMapping[item.path]//设置路由元信息temp.meta = item.rights//添加动态路由currentRoutes[2].children.push(temp)})})router .addRoutes(currentRoutes)
}export default router		

Login.vue

import {initDynamicRoutes } from '@/router.js'login(){this.Srefs.loginFormRef.validate(async valid =>{if(!valid)returnconst { data:res }= await this.$http.post('login', this.loginForm)if(res.meta.status !== 200) return this.$message.error('登录失败!')this.$store.commit('setRightList',res.rights)				this.$store.commit('setusername',res.data.username)sessionStorage.setItem('token',res.data.token)initDynamicRoutes()this.$message.success('登录成功')this.Srouter .push('/home')})
}

问题: 如果我们重新刷新的话动态路由就会消失,动态路由是在登录成功之后才会调用的,刷新的时候并没有调用,所以动态路由没有添加上
解决: 可以在app.vue中的created中调用添加动态路由的方法

`App.vue````javascript
import { initDynamicRoutes }from '@/router.js'
export default {name: 'app'created(){initDynamicRoutes()}
}

3.3 按钮的控制

虽然用户可以看到某些界面了,但是这个界面的一些按钮,该用户可能是没有权限的.因此,我们需要对组件中的一些按钮进行控制,用户不具备权限的按钮就隐藏或者禁用,而在这块中,可以把该逻辑放到自定义指令

  • permission.js
    自定义指令——显示还是隐藏按钮
import Vue from 'vue
import router from '@/router.js'
Vue.directive('permission', {inserted: function(el, binding){const action = binding.value.action//获取当前路由的metaconst currentRight =router.currentRoute.metaif(currentRight){if(currentRight.indexof(action)==-1){// 不具备权限const type = binding.value.effect//禁用按钮if(type ==='disabled'){el.disabled = trueel.classList.add('is-disabled')else {//不显示按钮el.parentNode.removechild(el)}}}
  • main.is
    引入自定义指令
import'./utils/permission.js'
  • router.js
    router中通过meta获取按钮权限
export function initDynamicRoutes(){const currentRoutes =router.options.routesconst rightList =store.state.rightListrightList.forEach(item =>{item.children.forEach(item =>{//下面是核心的两行,router中加入metaconst itemRule =ruleMapping[item.path]itemRule.meta=item.rightscurrentRoutes[2].children.push(itemRule)})
})
router.addRoutes(currentRoutes)
  • 使用指令
v-permission="{action:'add'}"
v-permission="{action:'delete', effect:'disabled'}"

3.4 请求和响应的控制

3.4.1 请求控制

  • 除了登录请求都得要带上token,这样服务器才可以鉴别你的身份
axios.interceptors.request.use(function(reg){const currentUrl =reg.ur1if(currenturl !== 'login'){req.headers.Authorization =sessionstorage.getItem('token')}return reg
})
  • 如果发出了非权限内的请求,应该直接在前端范围内组织,虽然这个请求发到服务器也会被拒绝
import axios from'axios'
import Vue from 'vue'
import router from '../router'
//配置请求的跟路径,目前用mock模拟数据,所以暂时把这一项注释起来
// axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
const actionMapping={get:'view',post:'add',put: 'edit',delete:'delete'
}axios.interceptors.request.use(function(req){const currentUrl=req.urlif(currenturl !== 'login'){req.headers.Authorization =sessionStorage.getItem('token')// 当前模块中具备的杈限// 查看 get请求// 增加post请求// 修改put请求// 删除delete请求const method =reg.method// 根据请求,得到是哪种操作const actión= actionMapping[method]// 判断action是否存在当前路由的权限中const rights =router.currentRoute.metaif(rights && rights.indexof(action)==-1){// 没有权限alert("没有权限")return Promise.reject(new Error('没有权限'))}}return reg
})axios.interceptors.response.use(function(res){return res
})
Vue.prototype.$http =axios

3.4.2 响应控制

  • 得到了服务器返回的状态码401,代表token超时或者被篡改了,此时应该强制跳转到登录界面
axios.interceptors.response.use(function(res){if(res.data.meta.status === 401){router.push('/login')sessionstorage.clear()window.location.reload()}return res
})

4. 小结

前端权限的实现之须要后端提供数据支持, 否则无法实现。
返回的权限数据的结构, 前后端需要沟通协商怎样的数据便用起来才最方便

4.1 菜单控制

  • 权限的数据需要在多组件之间共享, 因此采用vuex
  • 防止刷新界面, 权限数据丢失, 所以需要存在sessionStorage, 并目要保证两者的同步

4.2 界面控制

  • 路由的导航守卫可以防止跳过登录界面
  • 动态路由可以让不具备权限的界面的路由规则压根就不存在

4.3 按钮控制

  • 路由规则中可以增加路由元数据meta
  • 通过路由对象可以得到当前的路由规则以及存在此规则中的meta 数据
  • 自定义指令可以很方便的实现按钮控制

4.4 请求和响应控制

  • 请求拦截器和响应拦截器的使用
  • 请求方式的约定restful
    在这里插入图片描述

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

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

相关文章

开源六轴协作机械臂myCobot 280接入GPT4大模型!实现更复杂和智能化的任务

本文已经或者同济子豪兄作者授权对文章进行编辑和转载 引言 随着人工智能和机器人技术的快速发展,机械臂在工业、医疗和服务业等领域的应用越来越广泛。通过结合大模型和多模态AI,机械臂能够实现更加复杂和智能化的任务,提升了人机协作的效率…

easyexcel使用小结-未完待续

官网&#xff1a;https://easyexcel.opensource.alibaba.com/docs/current/ <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.1</version></dependency>一、读 1.1简单读 Getter…

Android-卷积神经网络(Convolutional Neural Network, CNN)

一个复杂且在Android开发中常见的算法是图像处理中的卷积神经网络(Convolutional Neural Network, CNN)。CNN被广泛用于图像识别、物体检测和图像分割等任务,其复杂性在于需要处理大量的图像数据、复杂的神经网络结构和高效的计算。 1. 卷积操作(Convolution) 数学原理:…

stm32——外部中断EXTI

上回书说到定时器的级联&#xff0c;今天来谈谈外部中断EXTI。我使用的是STM32F103C8T6的学习板。仅供大家参考。 什么是中断呢&#xff1f;中断是指计算机在执行程序的过程中&#xff0c;当出现某些异常情况或特殊事件&#xff08;例如外部设备请求、定时时间到达、程序错误等…

LeetCode 744, 49, 207

目录 744. 寻找比目标字母大的最小字母题目链接标签思路代码 49. 字母异位词分组题目链接标签思路代码 207. 课程表题目链接标签思路代码 744. 寻找比目标字母大的最小字母 题目链接 744. 寻找比目标字母大的最小字母 标签 数组 二分查找 思路 本题比 基础二分查找 难的一…

Java求解百钱买百鸡问题(课堂实例2)

目录 &#x1f495;&#x1f495;引言&#x1f495;&#x1f495; &#x1f60d;&#x1f60d;点关注编程梦想家&#xff08;大学生版&#xff09;-CSDN博客不迷路&#x1f495;&#x1f495; 一、问题背景----百鸡百钱_百度百科 (baidu.com) &#x1d465;&#x1d466;&a…

黑马点评报错@user_script:17: user_script:17: attempt to compare nil with number

后面发现是需要预先写入缓存seckill:stock:11&#xff0c;其中11是优惠券id 我数据库里面是11 &#xff0c;这里redis里面也写了11之后就好使了

html+css+JavaScript 实现两个输入框的反转动画

开发时遇到了一个输入框交换的动画 做完之后觉得页面上加些许过渡或动画&#xff0c;其变化虽小&#xff0c;却能极大的提升页面质感&#xff0c;给人一种顺畅、丝滑的视觉体验。它的实现过程主要是通过css中的transition和animation来实现的。平时在开发的时候增加一些动画效…

python安装PyTorch+cuda

1,最终结果 import torchprint(torch.cuda.is_available()) #显示True&#xff0c;则安装成功 print(torch.__version__)#打印当前PyTorch版本号。 print(torch.version.cuda)#打印当前CUDA版本号。 print(torch.backends.cudnn.version())# 打印当前cuDNN版本号。 print(torc…

vuepress创建步骤

背景 记录vuepress配置步骤&#xff0c;以便下次使用快速上手。 读此文章之前默认您已经学会了创建vuepress项目。vuepres快速开始 最终成品 doc.jeecgflow.com 配置步骤 创建.vuepress 目录。 你的文档目录下创建一个 .vuepress 目录。 创建.vuepress/config.js module.e…

【Whisper】WhisperX: Time-Accurate Speech Transcription of Long-Form Audio

Abstract Whisper 的跨语言语音识别取得了很好的结果&#xff0c;但是对应的时间戳往往不准确&#xff0c;而且单词级别的时间戳也不能做到开箱即用(out-of-the-box). 此外&#xff0c;他们在处理长音频时通过缓冲转录

法国工程师IMT联盟 密码学及其应用 2022年期末考试

1 密码学 1.1 问题1 对称加密&#xff08;密钥加密) 1.1.1 问题 对称密钥la cryptographie symtrique和公开密钥有哪些优缺点&#xff1f; 1.1.1.1 对称加密&#xff08;密钥加密)的优缺点 1.1.1.1.1 优点 加解密速度快encrypt and decrypt&#xff1a;对称加密算法通常基于…

四川蔚澜时代电子商务有限公司持续领跑抖音电商

在当今这个数字化飞速发展的时代&#xff0c;电子商务已成为推动经济增长的重要引擎。而在众多电商平台中&#xff0c;抖音电商以其独特的社交属性和年轻化的用户群体&#xff0c;逐渐崭露头角。四川蔚澜时代电子商务有限公司正是这股潮流中的佼佼者&#xff0c;他们专注于抖音…

【matlab 路径规划】基于改进遗传粒子群算法的药店配送路径优化

一 背景介绍 本文分享的是一个基于订单合并的订单分配和路径规划联合优化&#xff0c;主要背景是骑手根据客户需求&#xff0c;从药店取药之后进行配送&#xff0c;配送的过程中考虑路径的长度、客户的服务时间窗、车辆的固定成本等要素&#xff0c;经过建模和优化得到最优的配…

Qt 网络编程实战

一.获取主机的网络信息 需要添加network模块 QT core gui network主要涉及的类分析 QHostInfo类 QHostInfo::localHostName() 获取本地的主机名QHostInfo::fromName(const QString &) 获取指定主机的主机信息 addresses接口 QNetworkInterface类 QNetworkInterfac…

小试牛刀-区块链代币锁仓(Web页面)

Welcome to Code Blocks blog 本篇文章主要介绍了 [区跨链代币锁仓(Web页面)] ❤博主广交技术好友&#xff0c;喜欢我的文章的可以关注一下❤ 目录 1.编写目的 2.开发环境 3.实现功能 4.代码实现 4.1 必要文件 4.1.1 ABI Json文件(LockerContractABI.json) 4.2 代码详解…

挑战杯 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

7月8号直播预告 | 全国产EtherCAT运动控制器ZMC432HG及其EtherCAT驱动器与控制器常用回零模式介绍

EtherCAT运动控制边缘控制器是工业互联网的关键组件之一&#xff0c;结合丰富的运动控制功能、实时数据采集、处理和本地计算等&#xff0c;具备高度灵活的可编程性和出色的运动控制性能&#xff0c;为运动控制协同工业互联网应用带来巨大市场潜力&#xff0c;同时也使其成为企…

简单实现联系表单Contact Form自动发送邮件

如何实现简单Contact Form自动邮件功能&#xff1f;怎样简单设置&#xff1f; 联系表单不仅是访客与网站所有者沟通的桥梁&#xff0c;还可以收集潜在客户的信息&#xff0c;从而推动业务的发展。AokSend将介绍如何简单实现一个联系表单&#xff0c;自动发送邮件的过程&#x…

VPN 的入门介绍

VPN&#xff08;虚拟专用网络&#xff09; 简介 虚拟专用网络&#xff0c;简称虚拟专网&#xff08;VPN&#xff09;&#xff0c;其主要功能是在公用网络上建立专用网络&#xff0c;进行加密通讯。在企业网络中有广泛应用。VPN网关通过对数据包的加密和数据包目标地址的转换实…