亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue2.0用戶(hù)權(quán)限控制解決方案

 更新時(shí)間:2017年11月29日 10:48:20   投稿:laozhang  
這篇文章主要介紹了Vue2.0用戶(hù)權(quán)限控制解決方法以及源碼說(shuō)明,一起學(xué)習(xí)下。

Vue-Access-Control是一套基于Vue/Vue-Router/axios 實(shí)現(xiàn)的前端用戶(hù)權(quán)限控制解決方案,通過(guò)對(duì)路由、視圖、請(qǐng)求三個(gè)層面的控制,使開(kāi)發(fā)者可以實(shí)現(xiàn)任意顆粒度的用戶(hù)權(quán)限控制。

安裝

版本要求

Vue 2.0x
Vue-router 3.x
獲取

git:git clone https://github.com/tower1229/Vue-Access-Control.git

npm:npm i vue-access-control

運(yùn)行

//開(kāi)發(fā)
npm run dev

//構(gòu)建
npm build

概述

整體思路

會(huì)話(huà)開(kāi)始之初,先初始化一個(gè)只有登錄路由的Vue實(shí)例,在根組件created鉤子里將路由定向到登錄頁(yè),用戶(hù)登錄成功后前端拿到用戶(hù)token,設(shè)置axios實(shí)例統(tǒng)一為請(qǐng)求headers添加{"Authorization":token}實(shí)現(xiàn)用戶(hù)鑒權(quán),然后獲取當(dāng)前用戶(hù)的權(quán)限數(shù)據(jù),主要包括路由權(quán)限和資源權(quán)限,之后動(dòng)態(tài)添加路由,生成菜單,實(shí)現(xiàn)權(quán)限指令和全局權(quán)限驗(yàn)證方法,并為axios實(shí)例添加請(qǐng)求攔截器,至此完成權(quán)限控制初始化。動(dòng)態(tài)加載路由后,路由組件將隨之加載并渲染,而后展現(xiàn)前端界面。

為解決瀏覽器刷新路由重置的問(wèn)題,拿到token后要將其保存到sessionStorage,根組件的created鉤子負(fù)責(zé)檢查本地是否已有token,如果有則無(wú)需登錄直接用該token獲取權(quán)限并初始化,如果token有效且當(dāng)前路由有權(quán)訪(fǎng)問(wèn),將加載路由組件并正確展現(xiàn);若當(dāng)前路由無(wú)權(quán)訪(fǎng)問(wèn)將按路由設(shè)置跳轉(zhuǎn)404;如果token失效,后端應(yīng)返回4xx狀態(tài)碼,前端統(tǒng)一為axios實(shí)例添加錯(cuò)誤攔截器,遇到4xx狀態(tài)碼執(zhí)行退出操作,清除sessionStorage數(shù)據(jù)并跳轉(zhuǎn)到登錄頁(yè),讓用戶(hù)重新登錄。

最小依賴(lài)原則

Vue-Access-Control的定位是單一領(lǐng)域解決方案,除了Vue/Vue-Router/axios之外沒(méi)有其他依賴(lài),理論上可以無(wú)障礙的應(yīng)用到任何有權(quán)限控制需求的Vue項(xiàng)目中,項(xiàng)目基于webpack 模板開(kāi)發(fā)構(gòu)建,大多數(shù)新項(xiàng)目可以直接基于檢出代碼繼續(xù)開(kāi)發(fā)。需要說(shuō)明的是,項(xiàng)目額外引入的Element-UI和CryptoJS僅用于開(kāi)發(fā)演示界面,他們不是必須且與權(quán)限控制毫無(wú)關(guān)系,項(xiàng)目應(yīng)用中可以自行取舍。

目錄結(jié)構(gòu)

src/
 |-- api/     //接口文件
 |  |-- index.js    //輸出通用axios實(shí)例
 |  |-- account.js   //按業(yè)務(wù)模塊組織的接口文件,所有接口都引用./index提供的axios實(shí)例
 |-- assets/
 |-- components/
 |-- router/
 |  |-- fullpath.js   //完整路由數(shù)據(jù),用于匹配用戶(hù)的路由權(quán)限得到實(shí)際路由
 |  `-- index.js   //輸出基礎(chǔ)路由實(shí)例
 |-- views/
 |-- App.vue
 ·-- main.js

 

數(shù)據(jù)格式約定

路由權(quán)限數(shù)據(jù)必須是如下格式的對(duì)象數(shù)組,id和parent_id相同的兩個(gè)路由具有上下級(jí)關(guān)系,如果希望使用自定義格式的路由數(shù)據(jù),需要修改路由控制的相關(guān)實(shí)現(xiàn)。

[
 {
  "id": "1",
  "name": "菜單1",
  "parent_id": null,
  "route": "route1"
 },
 {
  "id": "2",
  "name": "菜單1-1",
  "parent_id": "1",
  "route": "route2"
 }
 ]

資源權(quán)限數(shù)據(jù)必須是如下格式的對(duì)象數(shù)組,每個(gè)對(duì)象代表一個(gè)RESTful請(qǐng)求,支持帶參數(shù)的url。

[
 {
  "id": "2c9180895e172348015e1740805d000d",
  "name": "賬號(hào)-獲取",
  "url": "/accounts",
  "method": "GET"
 },
 {
  "id": "2c9180895e172348015e1740c30f000e",
  "name": "賬號(hào)-刪除",
  "url": "/account/**",
  "method": "DELETE"
 }
]

路由控制

路由控制包括動(dòng)態(tài)注冊(cè)路由和動(dòng)態(tài)生成菜單兩部分。

動(dòng)態(tài)注冊(cè)路由

最初實(shí)例化的路由僅包括登錄和404兩個(gè)路徑,我們期待完整的路由是這樣的:

[{
 path: '/login',
 name: 'login',
 component: (resolve) => require(['../views/login.vue'], resolve)
}, {
 path: '/404',
 name: '404',
 component: (resolve) => require(['../views/common/404.vue'], resolve)
}, {
 path: '/',
 name: '首頁(yè)',
 component: (resolve) => require(['../views/index.vue'], resolve),
 children: [{
 path: '/route1',
 name: '欄目1',
 meta: {
  icon: 'icon-channel1'
 },
 component: (resolve) => require(['../views/view1.vue'], resolve)
 }, {
 path: '/route2',
 name: '欄目2',
 meta: {
  icon: 'ico-channel2'
 },
 component: (resolve) => require(['../views/view2.vue'], resolve),
 children: [{
  path: 'child2-1',
  name: '子欄目2-1',
  meta: {
  
  },
  component: (resolve) => require(['../views/route2-1.vue'], resolve)
 }]
 }]
}, {
 path: '*',
 redirect: '/404'
}]

那么接下來(lái)就需要獲取首頁(yè)以及其子路由們,思路是事先在本地存一份整個(gè)項(xiàng)目的完整路由數(shù)據(jù),然后根據(jù)用戶(hù)權(quán)限對(duì)完整路由進(jìn)行篩選。

篩選的實(shí)現(xiàn)思路是先將后端返回的路由數(shù)據(jù)處理成如下哈希結(jié)構(gòu):

let hashMenus = {
 "/route1":true,
 "/route1/route1-1":true,
 "/route1/route1-2":true,
 "/route2":true,
 ...
}

然后遍歷本地完整路由,在循環(huán)中將路徑拼接成上述結(jié)構(gòu)中的key格式,通過(guò)hashMenus[route]就可以判斷路由是否匹配,具體實(shí)現(xiàn)見(jiàn)App.vue文件中的getRoutes()方法。

如果后端返回的路由權(quán)限數(shù)據(jù)與約定不同,就需要自行實(shí)現(xiàn)篩選邏輯,只要能得到實(shí)際可用的路由數(shù)據(jù)就可以,最終使用addRoutes()方法將他們動(dòng)態(tài)添加到路由實(shí)例中,注意404頁(yè)面的模糊匹配一定要放在最后。

動(dòng)態(tài)菜單

路由數(shù)據(jù)可以直接用來(lái)生成導(dǎo)航菜單,但路由數(shù)據(jù)是在根組件中得到的,導(dǎo)航菜單存在于index.vue組件中,顯然我們需要通過(guò)某種方式共享菜單數(shù)據(jù),方法有很多,一般來(lái)說(shuō)首先想到的是Vuex,但菜單數(shù)據(jù)在整個(gè)用戶(hù)會(huì)話(huà)過(guò)程中不會(huì)發(fā)生改變,這并不是Vuex的最佳使用場(chǎng)景,而且為了盡量減少不必要的依賴(lài),這里用了最簡(jiǎn)單直接的方法,把菜單數(shù)據(jù)掛在根組件data.menuData上,在首頁(yè)里用this.$parent.menuData獲取。

另外,導(dǎo)航菜單很可能會(huì)有添加欄目圖標(biāo)的需求,這可以通過(guò)在路由中添加meta數(shù)據(jù)實(shí)現(xiàn),例如將圖標(biāo)class或unicode存到路由meta里,模板中就可以訪(fǎng)問(wèn)到meta數(shù)據(jù),用來(lái)生成圖標(biāo)標(biāo)簽。

在多角色系統(tǒng)中可能遇到的一個(gè)問(wèn)題是,不同角色有一個(gè)名字相同但功能不同的路由,比如說(shuō)系統(tǒng)管理員和企業(yè)管理員都有”賬號(hào)管理”這個(gè)路由,但他們的操作權(quán)限和目標(biāo)不同,實(shí)際上是兩個(gè)完全不同的界面,而Vue不允許多個(gè)路由同名,因此路由的name必須做區(qū)分,但把區(qū)分后的name顯示在前端菜單上會(huì)很不美觀,為了讓不同角色可以享有同一個(gè)菜單名稱(chēng),我們只要將這兩個(gè)路由的meta.name都設(shè)置成”賬號(hào)管理”,在模板循環(huán)時(shí)優(yōu)先使用meta.name就可以了。

菜單的具體實(shí)現(xiàn)可以參考views/index.vue。

視圖控制

視圖控制的目標(biāo)是根據(jù)當(dāng)前用戶(hù)權(quán)限決定界面元素顯示與否,典型場(chǎng)景是對(duì)各種操作按鈕的顯示控制。實(shí)現(xiàn)視圖控制的本質(zhì)是實(shí)現(xiàn)一個(gè)權(quán)限驗(yàn)證方法,輸入請(qǐng)求權(quán)限,輸出是否獲準(zhǔn)。然后配合v-if或jsx或自定義指令就能靈活實(shí)現(xiàn)各種視圖控制。

全局驗(yàn)證方法

驗(yàn)證方法的的實(shí)現(xiàn)本身很簡(jiǎn)單,無(wú)非是根據(jù)后端給出的資源權(quán)限做判斷,重點(diǎn)在于優(yōu)化方法的輸入輸出,提升易用性,經(jīng)過(guò)實(shí)踐總結(jié)最終使用的方案是,將權(quán)限跟請(qǐng)求同時(shí)維護(hù),驗(yàn)證方法接收請(qǐng)求對(duì)象數(shù)組為參數(shù),返回是否具有權(quán)限的布爾值。

請(qǐng)求對(duì)象格式:

//獲取賬戶(hù)列表
const request = {
 p: ['get,/accounts'],
 r: params => {
 return instance.get(`/accounts`, {params})
 }
}

權(quán)限驗(yàn)證方法$_has()的調(diào)用格式:

v-if="$_has([request])"

權(quán)限驗(yàn)證方法的具體實(shí)現(xiàn)見(jiàn)App.vue中Vue.prototype.$_has方法。

將權(quán)限驗(yàn)證方法全局混入,就可以在項(xiàng)目中很容易的配合v-if實(shí)現(xiàn)元素顯示控制,這種方式的優(yōu)點(diǎn)在于靈活,除了可以校驗(yàn)權(quán)限外,還可以在判斷表達(dá)式中加入運(yùn)行時(shí)狀態(tài)做更多樣性的判斷,而且可以充分利用v-if響應(yīng)數(shù)據(jù)變化的特點(diǎn),實(shí)現(xiàn)動(dòng)態(tài)視圖控制。

具體實(shí)現(xiàn)細(xì)節(jié)參考基于Vue實(shí)現(xiàn)后臺(tái)系統(tǒng)權(quán)限控制中的相關(guān)章節(jié)。

自定義指令

v-if的響應(yīng)特性是把雙刃劍,因?yàn)榕袛啾磉_(dá)式在運(yùn)行過(guò)程中會(huì)頻繁觸發(fā),但實(shí)際上在一個(gè)用戶(hù)會(huì)話(huà)周期內(nèi)其權(quán)限并不會(huì)發(fā)生變化,因此如果只需要校驗(yàn)權(quán)限的話(huà),用v-if會(huì)產(chǎn)生大量不必要的運(yùn)算,這種情況只需在視圖載入時(shí)校驗(yàn)一次即可,可以通過(guò)自定義指令實(shí)現(xiàn):

//權(quán)限指令
Vue.directive('has', {
 bind: function(el, binding) {
 if (!Vue.prototype.$_has(binding.value)) {
  el.parentNode.removeChild(el);
 }
 }
});

自定義指令內(nèi)部仍然是調(diào)用全局驗(yàn)證方法,但優(yōu)點(diǎn)在于只會(huì)在元素初始化時(shí)執(zhí)行一次,多數(shù)情況下都應(yīng)該使用自定義指令實(shí)現(xiàn)視圖控制。

請(qǐng)求控制

請(qǐng)求控制是利用axios攔截器實(shí)現(xiàn)的,目的是將越權(quán)請(qǐng)求在前端攔截掉,原理是在請(qǐng)求攔截器中判斷本次請(qǐng)求是否符合用戶(hù)權(quán)限,以決定是否攔截。

普通請(qǐng)求的判斷很容易,遍歷后端返回的的資源權(quán)限格式,直接判斷request.method和request.url是否吻合就可以了,對(duì)于帶參數(shù)的url需要使用通配符,這里需要根據(jù)項(xiàng)目需求前后端協(xié)商一致,約定好通配符格式后,攔截器中要先將帶參數(shù)的url處理成約定格式,再判斷權(quán)限,方案中已經(jīng)實(shí)現(xiàn)了以下兩種通配符格式:

1. 格式:/resources/:id
 示例:/resources/1
 url: /resources/**
 解釋?zhuān)阂粋€(gè)名詞后跟一個(gè)參數(shù),參數(shù)通常表示名詞的id
 
2. 格式:/store/:id/member
 示例:/store/1/member
 url:/store/*/member
 解釋?zhuān)簝蓚€(gè)名詞之間夾帶一個(gè)參數(shù),參數(shù)通常表示第一個(gè)名詞的id

對(duì)于第一種格式需要注意的是,如果你要發(fā)起一個(gè)url為"/aaa/bbb"的請(qǐng)求,默認(rèn)會(huì)被處理成"/aaa/**"進(jìn)行權(quán)限校驗(yàn),如果這里的”bbb”并不是參數(shù)而是url的一部分,那么你需要將url改成"/aaa/bbb/",在最后加一個(gè)”/“表示該url不需要轉(zhuǎn)化格式。

攔截器的具體實(shí)現(xiàn)見(jiàn)App.vue中的setInterceptor()方法。

如果你的項(xiàng)目還需要其他的通配符格式,只需要在攔截器中實(shí)現(xiàn)對(duì)應(yīng)的檢測(cè)和轉(zhuǎn)化方法就可以了。

演示及說(shuō)明

演示說(shuō)明:

DEMO項(xiàng)目中演示了動(dòng)態(tài)菜單、動(dòng)態(tài)路由、按鈕權(quán)限、請(qǐng)求攔截。

演示項(xiàng)目后端由rap2生成mock數(shù)據(jù),登錄請(qǐng)求通常應(yīng)該是POST方式,但因?yàn)閞ap2的編程模式無(wú)法獲取到非GET的請(qǐng)求參數(shù),因此只能用GET方式登錄,實(shí)際項(xiàng)目中不建議仿效;

另外登錄后獲取權(quán)限的接口本來(lái)不需要攜帶額外參數(shù),后端可以根據(jù)請(qǐng)求頭攜帶的token信息實(shí)現(xiàn)用戶(hù)鑒權(quán),但因?yàn)閞ap2的編程模式獲取不到headers數(shù)據(jù),因此只能增加一個(gè)”Authorization”參數(shù)用于生成模擬數(shù)據(jù)。

測(cè)試賬號(hào):

1. username: root
 password: 任意
2. username: client
 password: 任意

相關(guān)文章

  • vue中實(shí)現(xiàn)支持txt,docx,xlsx,mp4格式文件預(yù)覽功能(純前端)

    vue中實(shí)現(xiàn)支持txt,docx,xlsx,mp4格式文件預(yù)覽功能(純前端)

    對(duì)于Vue你可以實(shí)現(xiàn)文件的預(yù)覽功能,這篇文章主要給大家介紹了關(guān)于vue中實(shí)現(xiàn)支持txt,docx,xlsx,mp4格式文件預(yù)覽功能的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Vue頁(yè)面骨架屏注入方法

    Vue頁(yè)面骨架屏注入方法

    這篇文章主要介紹了Vue頁(yè)面骨架屏注入的操作,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • 對(duì)vue.js中this.$emit的深入理解

    對(duì)vue.js中this.$emit的深入理解

    下面小編就為大家分享一篇對(duì)vue.js中this.$emit的深入理解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • vue2配置scss的方法步驟

    vue2配置scss的方法步驟

    這篇文章主要介紹了vue2配置scss的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 詳解vue-Resource(與后端數(shù)據(jù)交互)

    詳解vue-Resource(與后端數(shù)據(jù)交互)

    本篇文章主要介紹了vue-Resource(與后端數(shù)據(jù)交互),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • Vue2 的12種組件通訊

    Vue2 的12種組件通訊

    之前文章我們描述給過(guò)Vue3 的七通信使用,今天中五篇文章我們?cè)賮?lái)看看Vue2 的通信使用寫(xiě)法的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-09-09
  • Vue組合式API如何正確解構(gòu)props不會(huì)丟失響應(yīng)性

    Vue組合式API如何正確解構(gòu)props不會(huì)丟失響應(yīng)性

    響應(yīng)式?API?賦予了組合式?API?一大坨可能性的同時(shí),代碼精簡(jiǎn),雖然但是,我們應(yīng)該意識(shí)到響應(yīng)性的某些陷阱,比如丟失響應(yīng)性,在本文中,我們將學(xué)習(xí)如何正確解構(gòu)?Vue?組件的?props,使得?props?不會(huì)丟失響應(yīng)性
    2024-01-01
  • vue3?頭像上傳?組件功能實(shí)現(xiàn)

    vue3?頭像上傳?組件功能實(shí)現(xiàn)

    這篇文章主要介紹了vue3頭像上傳組件功能,用到了自定義組件v-model的雙向綁定,使用axios + formData 上傳文件,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • vue element項(xiàng)目引入icon圖標(biāo)的方法

    vue element項(xiàng)目引入icon圖標(biāo)的方法

    這篇文章主要介紹了vue element項(xiàng)目引入icon圖標(biāo)的方法,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2018-06-06
  • vue刷新頁(yè)面后params參數(shù)丟失的原因和解決方法

    vue刷新頁(yè)面后params參數(shù)丟失的原因和解決方法

    這篇文章主要給大家介紹了vue刷新頁(yè)面后params參數(shù)丟失的原因和解決方法,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12

最新評(píng)論