路由權限校驗
路由配置檔案
src/router/index.js
,找到
asyncRoutes
這個數組,在需要配置權限的路由上添加
meta
屬性,
meta
是一個對象,
meta
對象上添加
roles
屬性,
roles
是一個數組,裡面可以放
admin
、
editor
兩個角色。
export const asyncRoutes = [
{ path: '/book',
component: Layout,
redirect: '/book/create',
meta: { title: '圖書管理', icon: 'documentation', roles: ['admin'] },
children: [
{
path: '/book/create',
component: () => import('@/views/book/create'),
meta: { title: '上傳圖書', icon: 'edit', roles: ['admin'] },
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
浏覽器通路某個路由的時候,首先會進入一個全局的路由守衛
router.beforeEach
,這部分代碼在
src/permission.js
檔案裡。以下步驟是路由守衛裡執行的一系列邏輯步驟:
router.beforeEach(async(to, from, next) => {
// 啟動進度條
NProgress.start()
// 設定頁面title
document.title = getPageTitle(to.meta.title)
// 從cookie中擷取token
const hasToken = getToken()
// 判斷token是否存在
// token存在
if (hasToken) {
// 判斷路由是否為 /login
// 是 /login
if (to.path === '/login') {
// 路由重定向到 /
next({ path: '/' })
NProgress.done()
} else {
// 擷取使用者角色
const hasRoles = store.getters.roles && store.getters.roles.length > 0
// 如果角色存在則進行下一步
if (hasRoles) {
next()
} else {
// 如果角色不存在
try {
// 擷取角色
const { roles } = await store.dispatch('user/getInfo')
// 根據roles生成動态路由
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
// 合并路由
router.addRoutes(accessRoutes)
// replace設定成true 為的是讓使用者登入進去之後點選浏覽器回退,會退到空白頁而不是登入頁
next({ ...to, replace: true })
} catch (error) {
// 如果出現異常 把token清空 roles清空 cookie清空
await store.dispatch('user/resetToken')
// 列印錯誤
Message.error(error || 'Has Error')
// 重定向到login 并帶上上次通路的路由
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* 如果token不存在 */
// 如果路由存在白名單裡
if (whiteList.indexOf(to.path) !== -1) {
// 那就通路此路由
next()
} else {
// 如果路由不存在白名單裡,那就跳轉到登入頁 并帶上上次通路的路由
next(`/login?redirect=${to.path}`)
// 結束滾動條
NProgress.done()
}
}
})
router.afterEach(() => {
// 結束滾動條
NProgress.done()
})
流程圖: