路由和權限校驗
Vue的中后台系統中會有對路由和權限進行配置,學習一波 vue-admin-element 中路由配置 。
git地址 : https://github.com/PanJiaChen/vue-element-admin
路由的處理邏輯分析
中后台路由場景分析
輸入一串地址 -> /xxx
- Cookie 中未存 Token 時:
- 訪問為 /login 時,直接訪問 /login
- 訪問為 /login 以外的路由:如 /dashboard 實際訪問路徑為 /login?redirect=%2Fdashboard ,登錄后直接重定向到 /dashboard
- Cookie 中獲取到 Token 時:
- 訪問為 /login 時, login 在白名單中,重定向到 / -> /dashboard
- 訪問為 /login?redirect=/xxx 時,重定向到 /xxx
- 訪問為 /xxx 時,直接訪問為 /xxx
路由邏輯源碼
第一步:在main.js 中加載了全局路由守衛
1 import './permission' // 全局路由守衛
第二步:permission.js 中定義了全局路由守衛
1 router.beforeEach(async(to, from, next) => { 2 // 啟動進度條 3 NProgress.start() 4 5 // 修改頁面標題 6 document.title = getPageTitle(to.meta.title) 7 8 // 從 Cookie 獲取 Token 9 const hasToken = getToken() 10 11 // 判斷 Token 是否存在 12 if (hasToken) { 13 if (to.path === '/login') { 14 // 如果當前路徑為 login 就重定向到首頁 15 next({ path: '/' }) 16 NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 17 } else { 18 // 判斷用戶的角色是否存在 19 const hasRoles = store.getters.roles && store.getters.roles.length > 0 20 // 如果用戶的角色存在,則直接訪問 21 if (hasRoles) { 22 next() 23 } else { 24 // 如果用戶的角色不存在 25 try { 26 // get user info 27 // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] 28 // 異步獲取用戶的角色 29 const { roles } = await store.dispatch('user/getInfo') 30 31 // generate accessible routes map based on roles 32 // 根據傳入的用戶角色信息,動態生成路由 33 const accessRoutes = await store.dispatch('permission/generateRoutes', roles) 34 35 // dynamically add accessible routes 36 // 調用 router.addRoutes 動態添加路由 37 router.addRoutes(accessRoutes) 38 39 // 使用 replace 訪問路由,不會在 history 中留下記錄 40 next({ ...to, replace: true }) 41 } catch (error) { 42 // 當獲取用戶 角色 和 獲取路由 過程中產生異常時進行 catch 異常處理 43 // remove token and go to login page to re-login 44 // 移除 Token 數據 45 await store.dispatch('user/resetToken') 46 // 顯示提示錯誤 47 Message.error(error || 'Has Error') 48 // 重定向到 login 頁面 49 next(`/login?redirect=${to.path}`) 50 // 停止進度條 51 NProgress.done() 52 } 53 } 54 } 55 } else { 56 /* 不存在 token*/ 57 // 判斷訪問的 URL 是否在白名單中 58 if (whiteList.indexOf(to.path) !== -1) { 59 // in the free login whitelist, go directly 60 next() 61 } else { 62 // 如果訪問的 URL 不在白名單中,則直接重定向到登錄頁面,並將訪問的 URL 添加到 redirect 參數中 63 next(`/login?redirect=${to.path}`) 64 NProgress.done() 65 } 66 } 67 })
Tip:吃水不忘打井人 - > [小慕讀書] 管理后台