由于element多用來做后端管理界面,所以這里給大家推薦一個用來做后端管理的element框架!(vue-element-admin)
直接進入主題:
1.對路由跳轉(zhuǎn)進行判斷,如果符合權(quán)限就允許,反之就不行
2.對跳轉(zhuǎn)頁面進行邏輯請求判斷,就是頁面數(shù)據(jù)需要一定的權(quán)限才能發(fā)送請求(這樣需要后端人員給你做,個人感覺不太現(xiàn)實,后端估計想干你)
3.根據(jù)權(quán)限,動態(tài)生成對應(yīng)的路由,什么權(quán)限擁有什么路由(vue-element-admin)就是這么做的,動態(tài)生成路由
常用方法一般都是:
?----------- v-if + router.beforeEach() ----------
由于后端管理界面涉及到,對登陸用戶的權(quán)限判斷,可能做的好點的后端管理頁面,要么把相對應(yīng)的跳轉(zhuǎn)事件進行隱藏或判斷,或者把跳轉(zhuǎn)頁面進行隱藏,我之前也是這樣做的,對跳轉(zhuǎn)的路由按鈕進行??v-if??判斷,然后再在router.beforeEach()進行路由判斷,這樣就可以防止部分用戶,根據(jù)請求地址來實現(xiàn)跳轉(zhuǎn)
-------------對跳轉(zhuǎn)的按鈕事件進行權(quán)限判斷-------------
這樣就比第一種方法更直接,對跳轉(zhuǎn)頁面的路由事件,添加一個方法,然后根據(jù)權(quán)限判斷,if和else,滿足就跳轉(zhuǎn),不滿足就return,如果想要提升一下用戶體驗度,就彈出一個消息提示框,說您暫無權(quán)限!這是不是更簡單
這樣的方法,最直觀,最簡單,也最方便!但是呢,用戶體驗度不是很好,而且權(quán)限是寫死的,不具備靈活性,但是并不妨礙這是一種好方法!!
vue-element-admin根據(jù)權(quán)限動態(tài)生成路由的方式
學習了一下vue-element-admin這個后端管理框架后:我就覺得它的這種動態(tài)生成路由的方式很新穎,也很厲害,所以再踩了幾個坑以后,就來記錄一下
構(gòu)建項目上:ts+vuex+cookie
思路:
第一步:
就是在你登陸以后,后端返回token,然后在請求成功的回調(diào)里面,又發(fā)送token去后端去獲取當前用戶的詳細信息,信息中包括了你這名用戶的權(quán)限,是否為管理員身份,還是次級管理員身份,然后將token存入cookie,將請求獲取到的數(shù)據(jù)存入vuex!假設(shè)這個存儲你權(quán)限的字段交roles,是個數(shù)組,類似:[’admin'] or ['Secondary']?
第二步:
這里要說明的是,路由表中會定義兩個路由表,一個為公共路由表,一個為動態(tài)路由表,公共路由表就是不需要權(quán)限也能去訪問,動態(tài)路由表顧名思義就是需要權(quán)限去獲取了!然后根據(jù)獲取到你的權(quán)限之后,會根據(jù)roles中的字段,去遍歷動態(tài)路由表中的對應(yīng)的路由表,然后將符合條件的路由表保存起來
第三步:最后將獲取到的符合權(quán)限的路由,合并到固定路由下面,通過router.addRouter(),當然了這里還是要用到router.beforeEach()去做路由判斷,讓權(quán)限更牢靠一點
具體實現(xiàn)方法:貼代碼
獲取用戶信息和權(quán)限
import?{?VuexModule,?Module,?Mutation,?Action,?getModule?}?from?'vuex-module-decorators'
import?{?login,UserInfo?}?from?'../../api/user'
import?{?getCookie,setCookie?}?from?'../../utils/cookies'
import?store?from?'@/store'
export?interface?usermodel{
????username:string,
????password:string,
????token:string
}
@Module({?dynamic:?true,?store,?name:?'user'?})
class?User?extends?VuexModule?implements?usermodel{
????public?username?=?""
????public?password?=?""
????public?token?=?getCookie('token')?||""
????public?roles:string[]?=?[]?
????@Mutation
????private?SET_TOKEN(token:string){
????????this.token?=?token
????}
????@Mutation
????private?SET_ROLES(roles:string[]){
????????this.roles?=?roles
????}
????@Mutation
????private?SET_NAME(name:string[]){
????????this.roles?=?name
????}
????@Action
????public?async?Login(userInfo:{username:string,password:string}){?//登陸獲取token
????????let?{?username,password?}?=?userInfo
????????username?=?username.trim()
????????const?data?=?await?login({username,password})
????????const?{?token?}?=?data?as?any
????????setCookie('token',token)
????????this.SET_TOKEN(token)
????}
????@Action
????public?async?getUserinfo(){?//根據(jù)token去獲取登陸用戶個人信息,判斷個人權(quán)限
????????if(this.token?==?""){
????????????console.log('token不存在或者已過期')
????????}
????????const?{data}?=?await?UserInfo(this.token)
????????if(!data){
????????????throw?Error('未查到此用戶,請重新登陸')
????????}
????????const?{?roles,name?}?=?data
????????if(!roles?||?roles.length<=0){
????????????throw?Error('您不屬于管理員范疇')
????????}
????????this.SET_ROLES(roles)
????????this.SET_NAME(name)
????}
}
export?const?UserModel?=?getModule(User)
根據(jù)權(quán)限篩選對應(yīng)路由
import?{?VuexModule,Module,Action,Mutation,getModule?}?from?'vuex-module-decorators'
import?{?asyncRoutes,constantRoutes?}?from?'@/router'
import?store?from?'@/store'
import?{?RouteConfig?}?from?'vue-router'
export?interface?IpermissionState{
????routes:RouteConfig[],
????dynamicRoutes:?RouteConfig[]
}
const?hasPermission?=?(roles:string[],route:RouteConfig)=>{??//判斷動態(tài)路由中的meta中是否包含你當前用戶的權(quán)限
????if(route.meta?&&?route.meta.roles)?{
????????return?roles.some(role?=>?route.meta.roles.includes(role))
????}else{
????????return?true
????}
}
export?const?filterAsyncRoutes?=?(routes:RouteConfig[],roles:string[]):any=>{??//遞歸查詢出動態(tài)路由中符合當前用戶權(quán)限的路由
????const?res:RouteConfig[]?=?[]
????routes.forEach(route?=>?{
????????const?r?=?{?...route?}
????????if(hasPermission(roles,r)){
????????????if(r.children){
????????????????r.children?=?filterAsyncRoutes(r.children,roles)
????????????}
????????????res.push(r)
????????}
????});
}
@Module({?dynamic:?true,?store,?name:?'permission'?})
class?Permission?extends?VuexModule?implements?IpermissionState{
????public?routes:RouteConfig[]?=?[]
????public?dynamicRoutes:RouteConfig[]?=?[]
????@Mutation
????private?SET_ROLES(routes:RouteConfig[]){??//合并固定路由和動態(tài)路由
????????this.routes?=?constantRoutes.concat(routes)?//合并之后的所有的路由
????????this.dynamicRoutes?=?routes?//獲取到的所有的動態(tài)的路由
????}
????@Action
????public?GenerateRoutes(roles:?string[])?{
????????let?accessedRoutes
????????if(roles.includes('admin')){??//判斷是否為管理員,如果是管理員就不用篩選路由,直接全部給出
????????????accessedRoutes?=?asyncRoutes
????????}else{
????????????accessedRoutes?=?filterAsyncRoutes(asyncRoutes,roles)??//如果是次級管理員,就篩選出符合次級管理員的路由
????????}
????????this.SET_ROLES(accessedRoutes)
????}
}
export?const?PermissionModule?=?getModule(Permission)
將符合權(quán)限的路由添加到固定路由上
import?router?from?'./router'
import?{?Route?}?from?'vue-router'
import?{?UserModel?}?from?'./store/models/user'
import?{?PermissionModule?}?from?'./store/models/permission'
const?whitelist?=?['/login','/auth-redirect']
router.beforeEach(async(to:Route,form:Route,next:any)=>{
????if(UserModel.token){
????????if(to.path?===?'/login'){
????????????next({path:'/'})
????????}else{
????????????if(UserModel.roles.length?===?0){
????????????????try{
????????????????????await?UserModel.getUserinfo()??//調(diào)用獲取用戶信息的方法
????????????????????const?roles?=?UserModel.roles
????????????????????PermissionModule.GenerateRoutes(roles)??//篩選出符合條件的路由
????????????????????router.addRoutes(PermissionModule.dynamicRoutes)?//添加路由
????????????????????next({?...to,?replace:?true?})? //這是會清除瀏覽器中的歷史記錄
????????????????}catch(err){
????????????????????return?console.log(err)
????????????????}
????????????}else{
????????????????next()
????????????}
????????}
????}else{
????????if(whitelist.indexOf(to.path)?!==?-1){
????????????next()
????????}else{
????????????next('/login')
????????}
????}
})
實現(xiàn)方法可能有些繞,有興趣的小伙伴可以去官網(wǎng)下載源碼去看看!多敲個兩遍就知道了