一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - vue.js - vue element后臺鑒權流程分析

vue element后臺鑒權流程分析

2022-02-27 17:12丶文竹 vue.js

這篇文章主要介紹了vue element后臺鑒權流程分析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言:

最近項目遇到一個管理系統,感覺權限配置挺有意思,記錄一下流程實現的過程,便于自己學習以及整理思路,部分思路整合在代碼的注釋中:

路由攔截鑒權常用的兩種方法

1:路由攔截:單純給路由加字段標識符,通過路由攔截實現
2:動態(tài)路由:第二種是通過路由的拆分另外需要后端的配合去實現的動態(tài)路由配置

比較:

路由攔截實現方式比較簡單,只需要簡單的在router.beforeEach中根據路由配置信息過濾頁面是否有權限前往改組件,若相對于的權限不夠則不前往相應的組件

動態(tài)路由實現相對比較復雜,并且需要后端的配合,本質是路由配置表分成兩部分,相應的不同用戶登錄的時候,是根據用戶權限信息過濾篩選除路由配置表,動態(tài)添加,而用戶沒有權限的部分則不渲染,更適合相對比較大型的后臺系統

注:本篇內容主要介紹動態(tài)路由鑒權實現方式

與動態(tài)路由相關的通常有以下幾個文件:

  • router.js
  • permission.js(全局的路由攔截文件)
  • store.js

router.js

router.js的路由配置表可以分為兩部分,公共路由以及動態(tài)權限路由,動態(tài)權限路由可以放在前端,鑒權的時候前端自己進行數組的過濾,也可以放在后端過濾,思路相同,下面介紹的是配置表都放在前端的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default new  Router({
routes:[
   
        path:'/login',
        name:'login',
        component:aa
    },
    
        path:'/home',
        name:'home',
        component:cc
    },
    ]
})

上面這個是一般項目的路由配置,現在我們需要做鑒權所以需要把路由配置表稍微拆分一下,拆成以下兩個數組:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import Vue from 'vue'
import Router from 'vue-router'
 
Vue.use(Router)
 
export const defauleRoute = [ //固定部分權限的數組,所有用戶都能訪問的路由
    
        path:'/login',
        component:aa
    },
]
 
export const  asyncRoute = [ //動態(tài)配置的路由表,工作之前需要過濾
    {
        path:'/order',
        name:'order',
        component:aa,
        meta:{
            system:'order'
        }
    }
    {
        path:'/roles',
        name:'roles',
        component:aa,
        meta:{
            system:'roles'
        }
    }
]
 
//注冊路由工作表
const createRouter = () => new Router({
      // mode: 'history', // require service support
      scrollBehavior: () => ({ y: 0 }),
      routes: constantRoutes
})
const router = createRouter()
 
//重置路由工作表,退出登錄的時候需要調用此方法
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher
}
 
export default router

permission.js permission文件主要做全局的路由攔截,以及路由根據用戶權限動態(tài)過濾等功能,那么這部分內容主要設涉及的就是兩個問題 什么時候去處理動態(tài)路由什么條件去處理路由

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import router from './router'
import store from './store'
import { getToken } from '@/utils/auth' // 自定義封裝存取token的方法
 
Route.beforeEach((to,from,next) =>{
    //取token,判斷用戶是否已登錄
    const  hasToken = getToken()
    if(hasToken ){
    //判斷用戶已登錄
        if(to.path === "/login"){
            /**
            *用戶已經登陸,但是還路由到login頁面,這代表用戶已經執(zhí)行了退出登錄的操
            *作,所以這個地方可以清一下token之類的,或者自定義寫一些邏輯
            */
            next()
        }else{
        /**
        *這里是已經登錄或者點擊了登錄按鈕,token已經存入localstorage,但是但是不路
        *由到login的情況如果沒有路由到/login,那么就直接讓他放行就行,在這里面我處
        *理一些東西,就是用戶既然已經登陸,并且可以直接放行,那么我們放
        *行之前,在這個地方需要做一些邏輯,就是判斷用戶的權限,然后根
        *據用戶的權限,把我們的動態(tài)配置的路由表中符合他權限的那幾條路
        *由給過濾出來,然后插入到路由配置表中去使用
        *
        *那么就涉及到兩個問題:
        *1:什么時候去處理動態(tài)路由(登陸之后,進入到首頁之前,也就
        *是next之前)
        *2:什么條件處理動態(tài)路由
        */
        
        /**
        *這地方可以先判斷一下store中的用戶權限列表長度是否為0,若長度為0,則代表用戶
        *是剛點擊了登錄按鈕,但是還沒有進入到頁面,這時候需要再去做一些權限過濾之類的
        *操作如果長度不為0代表鑒權流程都沒問題了,直接前往對應的組件就行
        *這一步主要是為了防止重復過濾數組,節(jié)約性能
        */
            if(store.getters.roles.length > 0){
                next()
            }else{
                //代碼如果走到了這個地方,代表用戶是已登錄。并且鑒權流程還沒走,
                //那么在這地方就需要去走鑒權流程
                store.dispatch('getRoles').then(res=>{
                    //這個地方的res是第三步那個地方的peomise中的resolve傳
                    //過來的,也就是權限信息的那個數組
                    store.dispatch('createRouters',res.data)
                    .then(res=>{
                        //這里是調用store創(chuàng)造動態(tài)路由的那個函數,這個地方可以把那
                        //個權限數組傳到這個函數內部,或者不在這里傳,這個
                        //函數內部直接去取自己state里面的roles的值也是一樣的
                        let  addRouters = store.getters('addRouters')
                        let  allRouters = store.getters('allRouters')
 
                        //添加動態(tài)路由部分到工作路由
                        router.addRoutes(accessRoutes)
                        //前往攔截的頁面
                        next({ ...to, replace: true })
                    }) 
                })
            }
        }
    } else {
        /**這里是處理沒有token的情況,也就是說這時候用戶還沒有登陸,那
        *如果沒用戶登錄,那么判斷用戶是不是去登錄頁面,如果是登錄
        *頁面,就直接放行,如果沒登陸就想去訪問主頁那種頁面,就讓
        *他重定向到登錄頁面
        */
        if(to.path == '/login'){
            //這地方可以判斷的仔細一點,不一定是去login的時候再讓他直接放行,而是
            //前往所有公共組件的時候,都直接讓他放行
            next()
        }else{
            next('/login')
        }
    }
})

 

store.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//在api文件夾中定義一個獲取此用戶的權限的接口,并且在這個actions中調用
import { getUserRole } from "../api/getRoles"  //獲取權限的接口
import { logout } from '../api/user'   //用戶退出登錄的接口
import { resetRouter } from './router'
import { removeToken } from '@/utils/auth' // 自定義封裝清除token的方法
 
//這個是過濾數組的方法,如果路由表是多層嵌套的,那么可以遞歸調用這個方法去過濾數組
//function hasPermission(roles, route) {
//  if (route.meta && route.meta.roles) {
//    return roles.some(role => route.meta.roles.includes(role))
//  } else {
//    return true
//  }
//}
 
//export function filterAsyncRoutes(routes, roles) {
//  const res = []
 
//  routes.forEach(route => {
//    const tmp = { ...route }
//    if (hasPermission(roles, tmp)) {
//      if (tmp.children) {
//        tmp.children = filterAsyncRoutes(tmp.children, roles)
//      }
//      res.push(tmp)
//    }
//  })
//
//  return res
//}
 
//引入默認路由以及動態(tài)路由
import  { defauleRoute , asyncRouter }  from '@/router'
const state = {
    roles:[]    //掉接口拿到的權限列表,假設數據格式為:["order","roles"],
    allRouters: [], //這個是全部整合以后,最終要工作的路由
    addRouters: [],//這個是根據權限動態(tài)匹配過濾出來部分的路由
}
      
const getters = {
    /**把state中的roles存入到這個getters中,那么其他獲取這個getters中的
    *roles的地方,只要原本的roles發(fā)生改變,其他地方的這個roles也就會發(fā)生
    *改變了,這個相當于是computed計算屬性
    */
    roles:state => state.roles
    allRouters:state => state.allRouters
    addRouters:state => state.addRouters
}
const mutations:{
    /**在下面的actions里面通過commit把權限信息的數組提交到這個地方,然后
    *這個地方把數組提交到state的roles
    */
    SetRoute(state,router)
        //這個地方的router就是根據用戶權限,過濾出來的路由表
        state.allRouters = defauleRoute.concat(router)
        state.addRouters = router
    }
    //把路由權限數組存儲到state
    setRoles(state,value){
        state.roles = value
    }
}
const actions:{
    //寫一個獲取當前登陸角色權限的請求,比如["/order","roles"],如果請求回
    //來的是這樣的,那么就代表這個角色的權限就是可以訪問 order路由以及
    //roles路由
    
    //獲取權限信息可能有兩種情況:除了下面這種權限信息是一個單獨的接口,
    //權限信息也可能跟著用戶登陸的接口就一并返回
    //獲取當前用戶的權限信息,并且存入到state中,這個權限信息,可能跟后
    //端在溝通的時候,他不會單獨寫成一個接口給你去請求,而是你在登陸請求
    //的時候就把用戶信息和這個此用戶的權限信息都一次性返回給你了,那就在
    //用戶登陸的時候就把這個權限信息存入到這個state中,也一
    //樣的,目的就是要把權限信息的數組存入到state中就行
    //獲取roles權限方法
    getRoles({commit},data){
        return new Promise(resolve,reject){
            //調用獲取用戶權限接口
            getUserRole().then(res =>{
                //這里返回的數據應該是一個權限信息的數組,如:["order","roles"]
                //把權限信息通過mutations存入到state
                commit('setRoles',res.data)
                resolve(res.data)
            })
        }
    })
    //根據權限過濾數組配置表的方法
    createRouters({ commit } , data ){
        return new Promise((resolve,reject) =>{
            let addRouters =  [ ]
            if(data.includes("admin"){
                addRouters = asyncRouter
            }else{
                //項目開發(fā)中路由數組可能是多層嵌套,那么這地方需要用上面自定義的方 
                //法通過遞歸的方式去過濾,此demo就只按一層數組處理
                //(filterAsyncRoutes)方法
                addRouters = asyncRouter.filter(item=>{
                    if(data.includes(item.meta.system) ){
                        return item
                    }
                })
            }
            
            
            //把這個匹配出來的權限路由傳到mutations中,讓mutations
            //把這個匹配出來的路由存入到state
            commit.("SetRoute",addRouters)
            resolve()  //這個地方要調用一下這個resolve,這樣外面訪可以通過
                       //.then拿到數組過濾成功的回調
        })
    },
    logout({ commit }) {
        return new Promise((resolve, reject) => {
          logout().then(() => {
            removeToken() // must remove  token  first
            resetRouter()
            commit('setRoles', [])
            commit('SetRoute', [])
            resolve()
          }).catch(error => {
            reject(error)
          })
        })
  },
}
export default {
    state,
    getters,
    mutations,
    actions
}

退出登錄:

?
1
2
3
4
5
6
7
8
9
10
async function logout(){
    try{
        const res = await store.dispatch.logout()
        if(res.code == 200){
            //退出登錄成功
        }
    }catch{
        //退出登錄失敗(出錯了)
    }
}

結尾:

代碼一大堆,其實思路很簡單,不過是拿到路由配置表,過濾數組,動態(tài)添加而已

項目參考github:vue-element-admin

到此這篇關于vue element后臺鑒權流程分析的文章就介紹到這了,更多相關vue element鑒權內容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_46311806/article/details/115479904

延伸 · 閱讀

精彩推薦
  • vue.jsVue中引入svg圖標的兩種方式

    Vue中引入svg圖標的兩種方式

    這篇文章主要給大家介紹了關于Vue中引入svg圖標的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    十里不故夢10222021-12-31
  • vue.js梳理一下vue中的生命周期

    梳理一下vue中的生命周期

    看過很多人講vue的生命周期,但總是被繞的云里霧里,尤其是自學的同學,可能js的基礎也不是太牢固,聽起來更是吃力,那我就已個人之淺見,以大白話...

    CRMEB技術團隊7992021-12-22
  • vue.js詳解vue 表單綁定與組件

    詳解vue 表單綁定與組件

    這篇文章主要介紹了vue 表單綁定與組件的相關資料,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下...

    Latteitcjz6432022-02-12
  • vue.js用vite搭建vue3應用的實現方法

    用vite搭建vue3應用的實現方法

    這篇文章主要介紹了用vite搭建vue3應用的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    Asiter7912022-01-22
  • vue.jsVue2.x-使用防抖以及節(jié)流的示例

    Vue2.x-使用防抖以及節(jié)流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節(jié)流的示例,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下...

    Kyara6372022-01-25
  • vue.jsVue項目中實現帶參跳轉功能

    Vue項目中實現帶參跳轉功能

    最近做了一個手機端系統,其中遇到了父頁面需要攜帶參數跳轉至子頁面的問題,現已解決,下面分享一下實現過程,感興趣的朋友一起看看吧...

    YiluRen丶4302022-03-03
  • vue.jsVue多選列表組件深入詳解

    Vue多選列表組件深入詳解

    這篇文章主要介紹了Vue多選列表組件深入詳解,這個是vue的基本組件,有需要的同學可以研究下...

    yukiwu6752022-01-25
  • vue.jsVue2.x 項目性能優(yōu)化之代碼優(yōu)化的實現

    Vue2.x 項目性能優(yōu)化之代碼優(yōu)化的實現

    這篇文章主要介紹了Vue2.x 項目性能優(yōu)化之代碼優(yōu)化的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    優(yōu)小U9632022-02-21
主站蜘蛛池模板: 日本高清在线精品一区二区三区 | 小货SAO边洗澡边CAO你动漫 | 日本精品久久久久久久久免费 | 亚洲 欧美 制服 校园 动漫 | 睡男神的这件小事小说在线阅读 | 美女靠逼的视频 | 调教麻麻成贱m | voyeur多毛厕所 | 古装一级无遮挡毛片免费观看 | 精品一区二区三区高清免费不卡 | 国产亚洲精品一区二区在线观看 | 大伊香蕉在线精品不卡视频 | 亚洲国产影院 | 修修视频在线观看 | 亚洲精品国产精品国自产观看 | 亚洲国产成人久久综合一区77 | 免费a漫 - 禁密天堂 | 免费黄色小说 | 久久大胆视频 | 无码国产成人午夜在线观看不卡 | 夫妇野外交换激情 | 嫩草影院精品视频在线观看 | 国产美女在线一区二区三区 | 1717she精品视频在线观看 | 成人免费视频在 | 日本精品一二三区 | 九九在线精品亚洲国产 | 日韩视频一区二区 | 成年人在线免费看 | 亚洲国产精品二区久久 | 免费精品国产在线观看 | 丝袜护士强制脚足取精 | 五月婷婷在线免费观看 | 四虎在线成人免费网站 | 久久免费看少妇高潮A片JA | 2022最新国产在线不卡a | 欧美精品一区二区在线观看 | 91精品啪在线观看国产91九色 | 天堂激情网 | 免费高清资源黄网站在线观看 | 日本在线观看视频 |