權限控制權限控制權限控制權限控制權限控制

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.pswp.cn/web/39670.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39670.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39670.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python pyecharts 模塊

pyecharts 是一個基于 ECharts.js 的 Python 可視化庫,用于生成各種類型的交互式圖表和數據可視化。它支持多種常見的圖表類型,如折線圖、柱狀圖、散點圖、餅圖等,可以在 Web 頁面中呈現,并且具有豐富的配置選項和樣式定制能力。 …

qt c++ 實現服務注冊、發布服務,最后被成功后回調

在Qt中實現服務注冊、發布服務,并在服務成功發布后執行回調,可以通過使用Qt的QLocalServer和QLocalSocket來實現本地服務通信,或者使用網絡服務如QTcpServer和QTcpSocket進行網絡服務的發布與發現。這里我們以本地服務為例來說明。 實現本地…

WIN32核心編程 - 進程操作(一) 進程基礎 - 創建進程 - 進程句柄

公開視頻 -> 鏈接點擊跳轉公開課程博客首頁 -> 鏈接點擊跳轉博客主頁 目錄 進程基礎 進程的定義與概念 進程的組成 創建進程 可執行文件 CreateProces 執行流程 GetStartupInfo 進程終止 進程句柄 創建進程 打開進程 進程提權 內核模擬 回溯對象 自身進…

SD NAND時序解析

一、SD NAND時序的重要性 在SD NAND的數據傳輸過程中,時序起著至關重要的作用。正確的時序確保了數據能夠準確無誤地在主機和SD NAND之間傳輸。 二、命令與讀寫時序 SD NAND的通信基于命令和數據傳輸,遵循以下時序規則: 命令與響應交互&…

安卓常用的控件

人不走空 🌈個人主頁:人不走空 💖系列專欄:算法專題 ?詩詞歌賦:斯是陋室,惟吾德馨 在Android開發中,控件(也稱為視圖或控件組件)是構建用戶界面的基本元素。它們…

MySQL之備份與恢復(三)

備份與恢復 邏輯備份還是物理備份 物理備份 物理備份有如下好處: 1.基于文件的物理備份,只需要將需要的文件復制到其他地方即可完成備份。不需要其他額外的工作來生成原始文件。2.物理備份的恢復可能就更簡單了,這取決于存儲引擎。對于MyISAM&#x…

C++_04

1、繼承 1.1 基本概念 繼承是面向對象編程(OOP)中的一個核心概念,特別是在C中。它允許一個類(稱為派生類或子類)繼承另一個類(稱為基類或父類)的屬性和方法。繼承的主要目的是實現代碼重用&…

康姿百德磁性床墊好不好,效果怎么樣靠譜嗎

康姿百德典雅款床墊,打造舒適睡眠新體驗 康姿百德床墊是打造舒適睡眠新體驗的首選,其設計能夠保護脊椎健康,舒展脊椎,讓您享受一夜好眠。康姿百德床墊的面料選擇也非常重要,其細膩親膚的針織面料給您帶來柔軟舒適的觸…

如何在操作使用ufw設置防火墻

UFW(簡單防火墻)是用于管理iptables防火墻規則的用戶友好型前端。它的主要目標是使iptables的管理更容易。 在學習Linux的時候大家一般都會關心命令,Posix API和桌面等,很少會去了解防護墻。其實除了一些網絡安全廠商提供的付費防…

交互案例:5大經典交互效果

文件格式:.rp(請與班主任聯系獲取原型文檔) 文件名稱:Axure交互案例:5大經典交互實現 文件大小:78.5 MB 文檔內容介紹 五大經典交互包括: 圖片手風琴 圖片懸浮放大 詳細說明切換 圖片全屏查…

【Ubuntu noble】apt 無法安裝軟件 Unable to locate package vim

宿主機以及 docker 無法定位軟件包 將 /etc/apt/sources.list.d/ubuntu.sources 修改為以下內容(主要是 Suites 字段增加了noble noble-updates) Types: deb URIs: http://archive.ubuntu.com/ubuntu/ Suites: noble noble-updates noble-backports Com…

無需啟動工程造價司法鑒定的情形

第一,當事人在訴訟前已經對建設工程價款結算達成協議。如果當事人在訴訟前已經對建設工程價款結算已經達成協議,意味著工程價款的結算金額在訴訟前已經確定,按照上述歸納的關于工程造價司法鑒定程序的啟動標準,則此時已無啟動工程…

--7.4

7.4 Springboot 1、什么是 SpringBoot Starters 是一系列依賴關系的集合,因為它的存在,項目的依賴之間的關系對我們來說變得簡單了。 2、SpringBootApplication 復合注解: EnableAutoConfigurationComponentScanConfiguration 3、Rest…

上位機GUI 第三彈

😊 😊 😊 從協議層面講,地質單元相當重要,調試模式,我只能義命令發送的索引碼作為,每個設備的區分方式,調試的情況,不在設備上設置任何東西,開機訪問地址和端口就能用 因為懶,直接將…

【代碼隨想錄】【算法訓練營】【第55天】 [42]接雨水 [84]柱狀圖中最大的矩形

前言 思路及算法思維,指路 代碼隨想錄。 題目來自 LeetCode。 day 55,又是一個周一,不能再堅持~ 題目詳情 [42] 接雨水 題目描述 42 接雨水 解題思路 前提:雨水形成的情況是凹的, 需要前中后3個元素,計算該元…

分治求解最大子數組

分治求解最大子數組 分治求解步驟 分:將數組分成左右兩部分治:遞歸地求解左半部分和右半部分的最大子數組合:計算跨越中點的最大子數組,并取三者中的最大值 具體實現 分: 將數組A分成兩部分 左半部分:從…

專業的TPM管理咨詢公司有哪些特點?

專業的TPM管理咨詢公司,作為現代企業管理和設備維護的重要合作伙伴,其特點不僅體現在技術能力和服務質量上,更在于其獨特的經營理念和方法論。以下是專業TPM管理咨詢公司所具備的顯著特點: 一、全面的技術實力與深厚的行業經驗 專…

迎接AI時代的新篇章:GPT-5 技術突破與未來展望

GPT-5 一年半後發布?對此你有何期待? 前言 在美國達特茅斯工程學院的一次採訪中,OpenAI 首席技術官米拉穆拉蒂透露,GPT-5 將在一年半後發布,並將其描述為從高中生智力水平躍升到博士生水平的飛躍。這一消息在科技界引…

Lambda表達式講解

簡介: Lambda表達式的使用場景非常廣泛,主要包括函數式編程、集合操作、排序、線程編程、GUI事件處理、數據處理、Web開發等。 函數式編程:Lambda表達式是函數式編程的重要特性,可以用于替代傳統的匿名內部類,簡化代碼,提高可讀性。 集合操作:Lambda表達式可以與集合…

word 轉pdf 中圖片不被壓縮的方法

word 轉pdf 中圖片不被壓縮的方法 法1: 調節word 選項中的圖片格式為不壓縮、高保真 法2: 1: word 中的圖片盡可能使用高的分辨率,圖片存為pnd或者 tif 格式(最高清) 2: 轉化為pdf使用打印機器,參數如下…