搜尋
首頁web前端js教程使用Vue2.0如何實現使用者權限控制

使用Vue2.0如何實現使用者權限控制

Jun 23, 2018 pm 04:23 PM
權限控制

這篇文章主要介紹了Vue2.0使用者權限控制解決方法以及原始碼說明,一起學習下。

Vue-Access-Control是一套基於Vue/Vue-Router/axios 實現的前端使用者權限控制解決方案,透過對路由、視圖、請求三個層面的控制,使開發者可以實現任意顆粒度的使用者權限控制。

安裝

版本要求

Vue 2.0x
Vue-router 3.x
取得

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

npm:npm i vue-access-control

#執行

//开发
npm run dev

//构建
npm build

概述

整體思路

會話開始之初,先初始化一個只有登入路由的Vue實例,在根組件created鉤子裡將路由定向到登錄頁,用戶登入成功後前端拿到用戶token,設定axios實例統一為請求headers添加{"Authorization":token}實現用戶鑑權,然後獲取當前用戶的權限數據,主要包括路由權限和資源權限,之後動態添加路由,生成選單,實現權限指令和全域權限驗證方法,並為axios實例添加請求攔截器,至此完成權限控制初始化。動態載入路由後,路由元件將隨之載入並渲染,而後展現前端介面。

為解決瀏覽器刷新路由重置的問題,拿到token後要將其保存到sessionStorage,根組件的created鉤子負責檢查本地是否已有token,如果有則無需登錄直接用該token取得權限並初始化,如果token有效且當前路由有權訪問,將加載路由組件並正確展現;若當前路由無權訪問將按路由設定跳轉404;如果token失效,後端應返回4xx狀態碼,前端統一為axios實例新增錯誤攔截器,遇到4xx狀態碼執行退出操作,清除sessionStorage資料並跳到登入頁,讓使用者重新登入。

最小依賴原則

Vue-Access-Control的定位是單一領域解決方案,除了Vue/Vue-Router/axios之外沒有其他依賴,理論上可以無障礙的應用到在任何有權限控制需求的Vue專案中,專案是基於webpack 範本開發構建,大多數新專案可以直接基於檢出程式碼繼續開發。需要說明的是,專案額外引入的Element-UI和CryptoJS僅用於開發演示介面,他們不是必須且與權限控制毫無關係,專案應用中可以自行取捨。

目錄結構

src/
 |-- api/     //接口文件
 |  |-- index.js    //输出通用axios实例
 |  |-- account.js   //按业务模块组织的接口文件,所有接口都引用./index提供的axios实例
 |-- assets/
 |-- components/
 |-- router/
 |  |-- fullpath.js   //完整路由数据,用于匹配用户的路由权限得到实际路由
 |  `-- index.js   //输出基础路由实例
 |-- views/
 |-- App.vue
 ·-- main.js

資料格式約定

#路由權限資料必須是如下格式的物件數組,id和parent_id相同的兩個路由具有上下級關係,如果希望使用自訂格式的路由數據,則需要修改路由控制的相關實作。

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

資源權限資料必須是如下格式的物件數組,每個物件代表一個RESTful請求,支援帶有參數的url。

[
 {
  "id": "2c9180895e172348015e1740805d000d",
  "name": "账号-获取",
  "url": "/accounts",
  "method": "GET"
 },
 {
  "id": "2c9180895e172348015e1740c30f000e",
  "name": "账号-删除",
  "url": "/account/**",
  "method": "DELETE"
 }
]

路由控制

路由控制包含動態註冊路由和動態產生選單兩部分。

動態註冊路由

最初實例化的路由只包含登入和404兩個路徑,我們期待完整的路由是這樣的:

[{
 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: '首页',
 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'
}]

那麼接下來就需要取得首頁以及其子路由們,思路是事先在本地存一份整個項目的完整路由數據,然後根據用戶權限對完整路由進行篩選。

篩選的實作想法是先將後端回傳的路由資料處理成如下雜湊結構:

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

然後遍歷本地完整路由,在循環中將路徑拼接成上述結構中的key格式,透過hashMenus[route]就可以判斷路由是否匹配,具體實作請參閱App.vue檔案中的getRoutes()方法。

如果後端回傳的路由權限資料與約定不同,就需要自行實作篩選邏輯,只要能得到實際可用的路由資料就可以,最終使用addRoutes()方法將他們動態加入到路由實例中,注意404頁面的模糊配對一定要放在最後。

動態選單

路由資料可以直接用來產生導覽選單,但路由資料是在根元件中得到的,導航選單存在於index.vue元件中,顯然我們需要透過某種方式共享選單數據,方法有很多,一般來說首先想到的是Vuex,但菜單數據在整個用戶會話過程中不會發生改變,這並不是Vuex的最佳使用場景,而且為了盡量減少不必要的依賴,這裡用了最簡單直接的方法,把選單資料掛在根元件data.menuData上,首頁用this.$parent.menuData取得。

另外,導航選單很可能會有添加欄位圖示的需求,這可以透過在路由中加入meta資料實現,例如將圖示class或unicode存到路由meta裡,模板就可以存取到meta數據,用來產生圖標標籤。

在多角色系统中可能遇到的一个问题是,不同角色有一个名字相同但功能不同的路由,比如说系统管理员和企业管理员都有”账号管理”这个路由,但他们的操作权限和目标不同,实际上是两个完全不同的界面,而Vue不允许多个路由同名,因此路由的name必须做区分,但把区分后的name显示在前端菜单上会很不美观,为了让不同角色可以享有同一个菜单名称,我们只要将这两个路由的meta.name都设置成”账号管理”,在模板循环时优先使用meta.name就可以了。

菜单的具体实现可以参考views/index.vue。

视图控制

视图控制的目标是根据当前用户权限决定界面元素显示与否,典型场景是对各种操作按钮的显示控制。实现视图控制的本质是实现一个权限验证方法,输入请求权限,输出是否获准。然后配合v-if或jsx或自定义指令就能灵活实现各种视图控制。

全局验证方法

验证方法的的实现本身很简单,无非是根据后端给出的资源权限做判断,重点在于优化方法的输入输出,提升易用性,经过实践总结最终使用的方案是,将权限跟请求同时维护,验证方法接收请求对象数组为参数,返回是否具有权限的布尔值。

请求对象格式:

//获取账户列表
const request = {
 p: ['get,/accounts'],
 r: params => {
 return instance.get(`/accounts`, {params})
 }
}

权限验证方法$_has()的调用格式:

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

权限验证方法的具体实现见App.vue中Vue.prototype.$_has方法。

将权限验证方法全局混入,就可以在项目中很容易的配合v-if实现元素显示控制,这种方式的优点在于灵活,除了可以校验权限外,还可以在判断表达式中加入运行时状态做更多样性的判断,而且可以充分利用v-if响应数据变化的特点,实现动态视图控制。

具体实现细节参考基于Vue实现后台系统权限控制中的相关章节。

自定义指令

v-if的响应特性是把双刃剑,因为判断表达式在运行过程中会频繁触发,但实际上在一个用户会话周期内其权限并不会发生变化,因此如果只需要校验权限的话,用v-if会产生大量不必要的运算,这种情况只需在视图载入时校验一次即可,可以通过自定义指令实现:

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

自定义指令内部仍然是调用全局验证方法,但优点在于只会在元素初始化时执行一次,多数情况下都应该使用自定义指令实现视图控制。

请求控制

请求控制是利用axios拦截器实现的,目的是将越权请求在前端拦截掉,原理是在请求拦截器中判断本次请求是否符合用户权限,以决定是否拦截。

普通请求的判断很容易,遍历后端返回的的资源权限格式,直接判断request.method和request.url是否吻合就可以了,对于带参数的url需要使用通配符,这里需要根据项目需求前后端协商一致,约定好通配符格式后,拦截器中要先将带参数的url处理成约定格式,再判断权限,方案中已经实现了以下两种通配符格式:

1. 格式:/resources/:id
 示例:/resources/1
 url: /resources/**
 解释:一个名词后跟一个参数,参数通常表示名词的id
 
2. 格式:/store/:id/member
 示例:/store/1/member
 url:/store/*/member
 解释:两个名词之间夹带一个参数,参数通常表示第一个名词的id

对于第一种格式需要注意的是,如果你要发起一个url为"/aaa/bbb"的请求,默认会被处理成"/aaa/**"进行权限校验,如果这里的”bbb”并不是参数而是url的一部分,那么你需要将url改成"/aaa/bbb/",在最后加一个”/“表示该url不需要转化格式。

拦截器的具体实现见App.vue中的setInterceptor()方法。

如果你的项目还需要其他的通配符格式,只需要在拦截器中实现对应的检测和转化方法就可以了。

演示及说明

演示说明:

DEMO项目中演示了动态菜单、动态路由、按钮权限、请求拦截。

演示项目后端由rap2生成mock数据,登录请求通常应该是POST方式,但因为rap2的编程模式无法获取到非GET的请求参数,因此只能用GET方式登录,实际项目中不建议仿效;

另外登录后获取权限的接口本来不需要携带额外参数,后端可以根据请求头携带的token信息实现用户鉴权,但因为rap2的编程模式获取不到headers数据,因此只能增加一个”Authorization”参数用于生成模拟数据。

测试账号:

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

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

解决输入框被输入法遮挡的问题

在vue+vuex+axios+echarts中如何实现中国地图

在vue中如何实现样式之间的切换

在JavaScript中如何实现图片变大

以上是使用Vue2.0如何實現使用者權限控制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。