上午發佈前,感受已經作完了,就接着擼jiiiiiin權限系統 ,但是我發現漏了一個東西,就是一更的時候,針對v-access
指令默認模式,經過校驗對應資源所需接口列表來檢查登陸用戶是否具備訪問權限,可是那個時候的對比是接口的url,數據結構以下:html
authorizeInterfaces
:前端
["admin/dels/*", "admin/search/*/*/*", "admin/*/*/*", "role/list/*", "admin/*"]
複製代碼
可是我接着寫的時候,發現不知足呀,我後臺的接口是RESTful類型的,因此必須校驗url+method
,那如今的數據結構就變成:vue
authorizeInterfaces
:git
[{url: "admin/dels/*", method: "DELETE"}, ....]
複製代碼
故由修改了一下,具體能夠參考下面的commit:github
修改rbac前端校驗模塊,使其支持RESTful類型接口校驗 ajax
對於使用就兩步: 1.增長了一個isRESTfulInterfaces
配置:正則表達式
/** * [*] 聲明`authorizeInterfaces`集合存儲的是RESTful類型的接口仍是常規接口 * 1. 若是是(true),則`authorizeInterfaces`集合須要存儲的結構就是: * [{url: 'admin/dels/*', method: 'DELETE'}] * 即進行接口匹配的時候會校驗類型 * 2. 若是不是(false),則`authorizeInterfaces`集合須要存儲的結構就是,即不區分接口類型: * ['admin/dels/*'] */
isRESTfulInterfaces = true
複製代碼
2.在登陸成功設置$vp.rabcUpdateAuthorizeInterfaces
已受權接口列表的時候,你們須要將數據結構構造好。spring
3.針對於RESTful類型接口:v-access="[{url: 'admin/search/*', method: 'POST'}]"
json
如今針對v-access
指令的值的使用,能夠有如下幾種狀況:後端
isRESTfulInterfaces
設置爲true
,注意這是默認設置,則使用下面的格式:v-access="[{url: 'admin/search/*', method: 'POST'}]"
// 或者若是隻有一個接口聲明
v-access="{url: 'admin/search/*/*/*', method: 'POST'}"
複製代碼
isRESTfulInterfaces
設置爲false
,則使用下面的格式:v-access="['admin', 'admin/*']"
複製代碼
v-access:alias="['LOGIN', 'WELCOME']"
v-access:alias="'LOGIN'"
複製代碼
隱藏
,可是也可使用下面的配置讓組件變爲半透明且不可用點擊:v-access:alias.disable="['LOGIN', 'WELCOME']"
v-access.disable="['admin', 'admin/*']"
複製代碼
就是加一個disable
而已;
:)
謝謝支持!
更新分割
權限控制無論先後端均可以簡單分爲:
而前端我和團隊,檢索了不少地方都沒有很成熟或者說可行的關於 RBAC基於角色的訪問控制相關的前端權限控制方案,多是咱們檢索的方法不對,亦或是你們都忙於其餘,沒有時間把本身的方法整理公佈出來,故咱們在原定計劃中,本身實踐了一把,下面和你們分享一下,有不對或者錯誤的地方,望指正。
若是你們點進來,應該都知道何爲RBAC,爲何須要使用了,故這裏對此不作過多解釋,RBAC基於角色的訪問控制,通常只會在管理端應用使用,故這個模塊不做爲默認模塊。
下面介紹一下vue-viewplus 一個簡化Vue應用開發的工具庫中的rabc.js 自定義RBAC權限控制模塊。
該模塊,意在爲前端應用提供rbac權限控制幫助。
其和login-state-check.js 身份認證權限控制模塊不一樣之處在於,該模塊提供了一下兩種權限控制手段:
v-access
指令,對比聲明的接口或資源別是否已經受權而login-state-check.js 身份認證權限控制模塊,則提供的是對非公共頁面的身份認證校驗檢查,其中維護了用戶的身份認證即登陸狀態,這種權限控制,更適合大多數應用,即給用戶使用的客戶端應用。
而當前模塊也依賴了登陸狀態,故能夠一塊兒複用;
實際案例:
名稱 | 渠道 | 簡介 |
---|---|---|
jiiiiiin權限系統 | PC端 | 一個先後端分離的內管基礎項目,並基於當前插件完成了RBAC前端權限控制 |
效果以下:
![]() |
![]() |
![]() |
![]() |
使用方法:
main.js入口文件:
import router from './router'
import ViewPlus from 'vue-viewplus'
import rbacModule from '@/plugin/vue-viewplus/rbac.js'
import viewPlusOptions from '@/plugin/vue-viewplus'
Vue.use(ViewPlus, viewPlusOptions)
ViewPlus.mixin(Vue, rbacModule, {
debug: true,
errorHandler(err) {
console.error(err)
},
moduleName: '自定義RBAC',
router,
publicPaths: ['/login'],
onLoginStateCheckFail(to, from, next) {
this.dialog(`您無權訪問【${to.path}】頁面`)
.then(() => {
// 防止用戶被踢出以後,被權限攔截致使訪問不了任何頁面,故這裏進行登陸狀態監測
if (this.isLogin()) {
next(false);
} else {
next('/login');
}
})
}
})
複製代碼
[*] 登陸用戶擁有訪問權限的路由path路徑集合
完成該配置,則頁面可訪問性控制就能夠正常工做
[*] 登陸用戶擁有訪問權限的後臺接口集合
[可選] 登陸用戶擁有訪問權限的資源別名集合
完成以上配置,則自定義v-access指令就能夠支持對應模式的配置
[可選] 是不是超級用戶
有些系統存在一個超級用戶角色,其能夠訪問任何資源、頁面,故若是設置,針對這個登陸用戶將不會作任何權限校驗,以便節省前端資源
// 開始請求登陸接口
AccountLogin(vm.$vp, {
username,
password,
imageCode
})
.then(async res => {
// 修改用戶登陸狀態
vm.$vp.modifyLoginState(true)
const menus = _delEmptyChildren(res.principal.admin.menus);
const authorizeResources = _parseAuthorizePaths(res.principal.admin.authorizeResources);
vm.$vp.rabcUpdateAuthorizedPaths(authorizeResources)
const authorizeInterfaces = _parseAuthorizeInterfaces(res.principal.admin.authorizeInterfaces);
vm.$vp.rabcUpdateAuthorizeInterfaces(authorizeInterfaces)
const isSuperAdminStatus = _parseUserRoleIsSuperAdminStatus(res.principal.admin.roles);
vm.$vp.rabcUpdateSuperAdminStatus(isSuperAdminStatus)
複製代碼
針對須要設置的權限集合,其都是扁平化的一維數組,格式相似:
authorizedPaths
和publicPaths
:
["/mngauth/admin", "/index", "/mngauth"]
複製代碼
authorizeInterfaces
:
["admin/dels/*", "admin/search/*/*/*", "admin/*/*/*", "role/list/*", "admin/*"]
複製代碼
authorizeResourceAlias
:
["MNG_USERMNG", "MNG_ROLEMNG"]
複製代碼
注意以上數組的值除了能夠配置爲字符串還能夠配置爲正則表達式:
[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]
複製代碼
<el-form v-access="['admin/search/*/*/*']" slot="search-inner-box" :inline="true" :model="searchForm" :rules="searchRules" ref="ruleSearchForm" class="demo-form-inline">
...
<el-form-item class="search-inner-btn-box">
<el-button size="small" type="primary" icon="el-icon-search" @click="onSearch">查詢</el-button>
<el-button size="small" icon="el-icon-refresh" @click="onCancelSubmit">重置</el-button>
</el-form-item>
</el-form>
複製代碼
完成以上配置便可讓正常使用當前模塊提供的權限控制服務,固然如$vp.modifyLoginState|$vp#isLogin
涉及到login-state-check.js 身份認證權限控制模塊
針對authorizeInterfaces
,後期將會用於在發送ajax請求以前,對待請求的接口和當前集合進行匹配,若是匹配失敗說明用戶就沒有請求權限,則直接不發送後臺請求,減小後端沒必要要的資源浪費,在完成這個權限匹配,前端基礎的權限規則就完整了。
其實實現下來沒有想象的那麼複雜,能夠點擊查看源碼
相較於理解這一塊,我以爲理解RBAC原則和表結構,才能更好的理解爲何要這麼控制,更多的關於後端關於這一塊的實踐,能夠參考jiiiiiin權限系統這個內管項目針對表結構的設計,其後臺使用的是spring security來完成後端的RBAC權限控制,並針對當前前端權限須要和vue router path進行了細微變化,相較於傳統的RBAC 金典5張表的設計。
也請你們多多支持 :)
下面是改模塊的api描述:
debug|errorHandler|router|installed
配置,能夠查看全局通用配置
/** * [*] 系統公共路由path路徑集合,便可以讓任何人訪問的頁面路徑 * {Array<Object>} * <p> * 好比登陸頁面的path,由於登陸以前咱們是沒法判斷用戶是否能夠訪問某個頁面的,故須要這個配置,固然若是須要這個配置也能夠在初始化插件以前從服務器端獲取,這樣先後端動態性就更高,可是通常沒有這種需求:) * <p> * 數組中的item,能夠是一個**正則表達式字面量**,如`[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]`,也能夠是一個字符串 * <p> * 匹配規則:若是在`LoginStateCheck#publicPaths`**系統公共路由path路徑集合**中,那麼就直接跳過權限校驗 */
publicPaths = []
複製代碼
/** * [*] 登陸用戶擁有訪問權限的路由path路徑集合 * {Array<Object>} * <p> * 數組中的item,能夠是一個**正則表達式字面量**,如`[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]`,也能夠是一個字符串 * <p> * 匹配規則:若是在`LoginStateCheck#authorizedPaths`**須要身份認證規則集**中,那麼就須要查看用戶是否登陸,若是沒有登陸就拒絕訪問 */
authorizedPaths = []
複製代碼
/** * [*] 登陸用戶擁有訪問權限的後臺接口集合 * {Array<Object>} * <p> * 1.在`v-access`指令配置爲url(默認)校驗格式時,將會使用該集合和指令聲明的待審查受權接口列表進行匹配,若是匹配成功,則指令校驗經過,不然校驗不經過,會將對應dom元素進行處理 * 2.TODO 將會用於在發送ajax請求以前,對待請求的接口和當前集合進行匹配,若是匹配失敗說明用戶就沒有請求權限,則直接不發送後臺請求,減小後端沒必要要的資源浪費 * <p> * 數組中的item,能夠是一個**正則表達式字面量**,如`[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]`,也能夠是一個字符串 * <p> * 匹配規則:將會用於在發送ajax請求以前,對待請求的接口和當前集合進行匹配,若是匹配失敗說明用戶就沒有請求權限,則直接不發送後臺請求,減小後端沒必要要的資源浪費 */
authorizeInterfaces = []
複製代碼
/** * [可選] 登陸用戶擁有訪問權限的資源別名集合 * {Array<Object>} * <p> * 數組中的item,能夠是一個**正則表達式字面量**,如`[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]`,也能夠是一個字符串 * <p> * 匹配規則:由於若是都用`LoginStateCheck#authorizeInterfaces`接口進行匹配,可能有一種狀況,訪問一個資源,其須要n個接口,那麼咱們在配置配置權限指令:v-access="[n, n....]"的時候就須要聲明全部須要的接口,就會須要對比屢次, * 當咱們系統的接口集合很大的時候,勢必會成爲一個瓶頸,故咱們能夠爲資源聲明一個別名,這個別名則能夠表明這n個接口,這樣的話就從n+減小到n次匹配; */
authorizeResourceAlias = []
複製代碼
/** * [*] `$vp::onLoginStateCheckFail(to, from, next)` * <p> * 權限檢查失敗時被回調 */
onLoginStateCheckFail = null
複製代碼
/** * 代理`$vp#login-state-check`模塊的同名方法,以實如今登出、會話超時踢出的時候清理本模塊維護的登陸以後設置的狀態 * @param status */
modifyLoginState(status = false)
複製代碼
/** * 【可選】有些系統存在一個超級用戶角色,其能夠訪問任何資源、頁面,故若是設置,針對這個登陸用戶將不會作任何權限校驗,以便節省前端資源 * @param status */
rabcUpdateSuperAdminStatus(status)
複製代碼
/** * 添加受權路徑集合 * 如:登陸完成以後,將用戶被受權能夠訪問的頁面`paths`添加到`LoginStateCheck#authorizedPaths`中 * @param paths */
rabcAddAuthorizedPaths(paths)
複製代碼
/** * 更新受權路徑集合 * @param paths */
rabcUpdateAuthorizedPaths(paths)
複製代碼
/** * 更新資源別名集合 * @param alias */
rabcUpdateAuthorizeResourceAlias(alias)
複製代碼
/** * 添加資源別名集合 * @param alias */
rabcAddAuthorizeResourceAlias(alias)
複製代碼
/** * 更新公共路徑集合 * @param paths */
rabcUpdatePublicPaths(paths)
複製代碼
/** * 添加公共路徑集合 * @param paths */
rabcAddPublicPaths(paths)
複製代碼
若是你們以爲有用,請你們多多支持,更多的模塊請點擊查看