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

news2025/1/12 20:53:49

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 = data
			sessionStorage.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:"/welcome
			children:[
			{ 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.routes
	const rightList =store.state.rightList
	rightList.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)return
		const { 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
		//获取当前路由的meta
		const currentRight =router.currentRoute.meta
		if(currentRight){
			if(currentRight.indexof(action)==-1){
				// 不具备权限
				const type = binding.value.effect
				//禁用按钮
				if(type ==='disabled'){
					el.disabled = true
					el.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.routes
	const rightList =store.state.rightList
	rightList.forEach(item =>{
		item.children.forEach(item =>{
			//下面是核心的两行,router中加入meta
			const itemRule =ruleMapping[item.path]
			itemRule.meta=item.rights
			currentRoutes[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.ur1
	if(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.url
	if(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.meta
		if(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.coloradmin.cn/o/1888786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.2.3、冒泡排序

代码 #include <iostream> using namespace std;int main() {//冒泡排序升序int arr[9] { 4,2,8,0,5,7,1,3,9 };cout << "排序前&#xff1a;" << endl;for (int i 0; i < 9; i){cout << arr[i] << " ";}cout <<…

python-图像模糊处理(赛氪OJ)

[题目描述] 给定 n 行 m 列的图像各像素点的灰度值&#xff0c;要求用如下方法对其进行模糊化处理&#xff1a; 1. 四周最外侧的像素点灰度值不变。 2. 中间各像素点新灰度值为该像素点及其上下左右相邻四个像素点原灰度值的平均&#xff08;四舍五入&#xff09;输入&#xff…

pydub、ffmpeg 音频文件声道转换、采样率更改

转换成mono单声道 from pydub import AudioSegment# 加载MP3文件 mp3_file_path r"E:\allchat\output.wav" audio_segment AudioSegment.from_mp3(mp3_file_path)# 转换为单声道 audio_segment audio_segment.set_channels(1)# 导出为单声道MP3文件 mono_mp3_fil…

LinuxRT启动Veristand项目的配置文件

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

c语言回顾-数组(全网最详细,哈哈哈)

目录 前言&#xff0c;和小编一起感受数组的魅力&#xff01;&#xff01;&#xff01; 1.数组的概念 2.一维数组的创建和初始化 2.1数组创建 2.2数组的初始化 2.3数组的类型 3.一维数组的使用 3.1数组下标 3.2数组元素的输入输出 小结&#xff1a; 4.一维数组在内存…

SpringBoot环境集成 sms4j短信聚合

SpringBoot环境集成 sms4j短信聚合 官方文档 前言 在正式使用sms4j短信功能之前&#xff0c;请详细阅读本文档&#xff0c;依照本篇流程进行操作和配给&#xff0c;即可解决大部分问题&#xff0c;如对我们的文档有建议&#xff0c;请联系开发者团队&#xff0c; 我们将根据可…

Spring与Quartz整合

Quartz框架是一个轻量级的任务调度框架&#xff0c;它提供了许多内置的功能&#xff0c;包括&#xff1a;支持作业的调度、集群调度、持久化、任务持久化、任务依赖、优先级、并发控制、失败重试等。同时也支持自定义作业类型和触发器类型。与Spring整合步骤如下&#xff1a; …

怎么参与场外期权?

今天期权懂带你了解怎么参与场外期权&#xff1f; 目前个人投资者暂时还不能直接参与场外个股期权&#xff0c;因为场外个股期权现在只能机构来进行交易。 所以个人投资者目前只能通过机构通道来进行操作&#xff0c;类似期权懂&#xff0c;找到期权懂经理&#xff0c;然后通…

思维,CF 739A - Alyona and mex

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 739A - Alyona and mex 二、解题报告 1、思路分析 我们考虑区间mex运算的值最大也就是区间长度&#xff0c;所以我们最大值的上界就是所有区间中的最小长度&#xff0c;假如记为mi 我们一定可以构造出答案…

详解HTTP:常用的密钥交换算法RSA与ECDHE

HTTPS 常用的密钥交换算法&#xff1a;RSA 与 ECDHE 在 HTTPS 中&#xff0c;密钥交换算法扮演了至关重要的角色&#xff0c;确保数据在传输过程中的安全性。目前常用的密钥交换算法主要有两种&#xff1a;RSA 和 ECDHE。相比于较为传统的 RSA&#xff0c;ECDHE 由于具备前向安…

软连接迁移 Docker 的默认安装(存储)目录

前言 经常我们会拿到一些别人装好的服务器&#xff0c;需要在这些系统上启动我们的docker服务。 但是这些“专业人员”呢&#xff0c;有时候就会有非常不专业的操作&#xff0c;比如他把根目录/只划分50GB&#xff0c;/home却有51TB。这个时候就会导致我们的服务器还有很多空间…

java+mysql教师管理系统

完整源码地址 教师信息管理系统使用命令行交互的方式及数据库连接实现教师信息管理系统&#xff0c;该系统旨在实现教师信息的管理&#xff0c;并根据需要进行教师信息展示。该软件的功能有如下功能 (1)基本信息管理(教师号、姓名、性别、出生年月、职称、学历、学位、教师类型…

工业实时操作系统对比:鸿道Intewell跟rt-linux有啥区别

Intewell和RT-Linux是两种不同的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;它们具有各自独特的特点和优势。以下是Intewell操作系统的一些关键特性&#xff0c;以及与RT-Linux的比较&#xff1a; 自主研发&#xff1a;Intewell是由科东软件自主研发的工业嵌入式实…

监控与安全服务

kali 系统 nmap扫描 网段的扫描 使用脚本扫描 使用john破解密码 哈希算法是一种单向加密的算法&#xff0c;也就是将原始数据生成一串“乱码”只能通过原始数据&#xff0c;生成这串“乱码”&#xff0c;但是不能通过“乱码”回推出原始数据相同的原始数据&#xff0c;生成的乱…

数据治理体系建设方案

数据治理体系建设方案 在当前的大数据时代&#xff0c;数据已经成为企业核心资产之一&#xff0c;其管理与治理的重要性愈加凸显。有效的数据治理体系不仅能提升数据质量和数据使用的效率&#xff0c;还能为企业创造更多的商业价值。本文将详细阐述数据治理的重要性、核心要素…

星辰资讯 | TiUP v1.16 发版,支持 PD 微服务

如果你对 TiDB 还不太了解&#xff0c;或者你对数据库安装部署的认知仍然停留在手动和脚本时代&#xff0c;那么&#xff0c;请先戳这里了解一下 TiUP 神器&#xff1a; 震惊&#xff01;数据库小白装国产数据库只需10分钟&#xff01; TiDB 7.x 源码编译之 TiUP 篇 TiUP&#…

师傅们 ~ 2024HW一手资料

各位师傅们&#xff0c;2024HW来了&#xff01; 从2026年开始&#xff0c;随着我国对网络安全的重视&#xff0c;涉及单位不断增加&#xff0c;越来越多单位和个人都加入到HW当中。 2024HW就在眼前&#xff0c; 那么还有不了解或者还没投简历面试的朋友们&#xff0c;需要注意…

Python23 使用Tensorflow实现线性回归

TensorFlow 是一个开源的软件库&#xff0c;用于数值计算&#xff0c;特别适用于大规模的机器学习。它由 Google 的研究人员和工程师在 Google Brain 团队内部开发&#xff0c;并在 2015 年首次发布。TensorFlow 的核心是使用数据流图来组织计算&#xff0c;使得它可以轻松地利…

​​​​Linux LVS 负载均衡群集

在业务量达到一定量的时候&#xff0c;往往单机的服务是会出现瓶颈的。此时最常见的方式就是通过负载均衡来进行横向扩展。其中我们最常用的软件就是 Nginx。通过其反向代理的能力能够轻松实现负载均衡&#xff0c;当有服务出现异常&#xff0c;也能够自动剔除。但是负载均衡服…

GB28181百万路视频接入

重定向 国标28181在设计时就考虑了&#xff0c;省区县多层级接入&#xff0c;接入上限就考虑了呼叫重定向&#xff1a; IETF RFC3261 规定的SIP逻辑实体,负责规划SIP呼叫路由。它将获得的呼叫下一跳地址信息 告诉呼叫方,以使呼叫方根据此地址直接向下一跳发出请求,此后重定向服…