Skip to content

Commit 0c6e45e

Browse files
committed
refactor permission
1 parent e1d6189 commit 0c6e45e

File tree

6 files changed

+83
-71
lines changed

6 files changed

+83
-71
lines changed

src/layout/components/Navbar.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ export default {
7979
},
8080
async logout() {
8181
await this.$store.dispatch('user/logout')
82-
// In order to re-instantiate the vue-router object to avoid bugs
83-
location.reload()
82+
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
8483
}
8584
}
8685
}

src/permission.js

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,66 +7,64 @@ import { getToken } from '@/utils/auth' // get token from cookie
77

88
NProgress.configure({ showSpinner: false }) // NProgress Configuration
99

10-
// permission judge function
11-
function hasPermission(roles, permissionRoles) {
12-
if (roles.includes('admin')) return true // admin permission passed directly
13-
if (!permissionRoles) return true
14-
return roles.some(role => permissionRoles.indexOf(role) >= 0)
15-
}
16-
1710
const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist
1811

19-
router.beforeEach((to, from, next) => {
20-
NProgress.start() // start progress bar
21-
if (getToken()) {
22-
// determine if there has token
12+
router.beforeEach(async(to, from, next) => {
13+
// start progress bar
14+
NProgress.start()
15+
16+
// determine whether the user has logged in
17+
const hasToken = getToken()
2318

24-
/* has token*/
19+
if (hasToken) {
2520
if (to.path === '/login') {
21+
// if is logged in, redirect to the home page
2622
next({ path: '/' })
27-
NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
23+
NProgress.done()
2824
} else {
29-
if (store.getters.roles.length === 0) {
30-
// 判断当前用户是否已拉取完user_info信息
31-
store
32-
.dispatch('user/getInfo')
33-
.then(res => {
34-
// 拉取user_info
35-
const { roles } = res // note: roles must be a object array! such as: [{id: '1', name: 'editor'}, {id: '2', name: 'developer'}]
36-
store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
37-
// 根据roles权限生成可访问的路由表
38-
router.addRoutes(accessRoutes) // 动态添加可访问路由表
39-
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
40-
})
41-
})
42-
.catch(err => {
43-
store.dispatch('user/resetToken').then(() => {
44-
Message.error(err)
45-
next({ path: '/' })
46-
})
47-
})
25+
// determine whether the user has obtained his permission roles through getInfo
26+
const hasRoles = store.getters.roles && store.getters.roles.length > 0
27+
if (hasRoles) {
28+
next()
4829
} else {
49-
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
50-
if (hasPermission(store.getters.roles, to.meta.roles)) {
51-
next()
52-
} else {
53-
next({ path: '/401', replace: true, query: { noGoBack: true }})
30+
try {
31+
// get user info
32+
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
33+
const { roles } = await store.dispatch('user/getInfo')
34+
35+
// generate accessible routes map based on roles
36+
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
37+
38+
// dynamically add accessible routes
39+
router.addRoutes(accessRoutes)
40+
41+
// hack method to ensure that addRoutes is complete
42+
// set the replace: true, so the navigation will not leave a history record
43+
next({ ...to, replace: true })
44+
} catch (error) {
45+
// remove token and go to login page to re-login
46+
await store.dispatch('user/resetToken')
47+
Message.error(error || 'Has Error')
48+
next(`/login?redirect=${to.path}`)
49+
NProgress.done()
5450
}
55-
// 可删 ↑
5651
}
5752
}
5853
} else {
5954
/* has no token*/
55+
6056
if (whiteList.indexOf(to.path) !== -1) {
61-
// 在免登录白名单,直接进入
57+
// in the free login whitelist, go directly
6258
next()
6359
} else {
64-
next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
65-
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
60+
// other pages that do not have permission to access are redirected to the login page.
61+
next(`/login?redirect=${to.path}`)
62+
NProgress.done()
6663
}
6764
}
6865
})
6966

7067
router.afterEach(() => {
71-
NProgress.done() // finish progress bar
68+
// finish progress bar
69+
NProgress.done()
7270
})

src/router/index.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ export const constantRoutes = [
105105
}
106106
]
107107

108-
export default new Router({
109-
// mode: 'history', // require service support
110-
scrollBehavior: () => ({ y: 0 }),
111-
routes: constantRoutes
112-
})
113-
114108
export const asyncRoutes = [
115109
{
116110
path: '/permission',
@@ -383,3 +377,19 @@ export const asyncRoutes = [
383377

384378
{ path: '*', redirect: '/404', hidden: true }
385379
]
380+
381+
const createRouter = () => new Router({
382+
// mode: 'history', // require service support
383+
scrollBehavior: () => ({ y: 0 }),
384+
routes: constantRoutes
385+
})
386+
387+
const router = createRouter()
388+
389+
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
390+
export function resetRouter() {
391+
const newRouter = createRouter()
392+
router.matcher = newRouter.matcher // reset router
393+
}
394+
395+
export default router

src/store/modules/permission.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ const mutations = {
4747
}
4848

4949
const actions = {
50-
generateRoutes({ commit }, data) {
50+
generateRoutes({ commit }, roles) {
5151
return new Promise(resolve => {
52-
const { roles } = data
5352
let accessedRoutes
5453
if (roles.includes('admin')) {
5554
accessedRoutes = asyncRoutes

src/store/modules/user.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { login, logout, getInfo } from '@/api/user'
22
import { getToken, setToken, removeToken } from '@/utils/auth'
3+
import router, { resetRouter } from '@/router'
34

45
const state = {
56
token: getToken(),
@@ -78,6 +79,7 @@ const actions = {
7879
commit('SET_TOKEN', '')
7980
commit('SET_ROLES', [])
8081
removeToken()
82+
resetRouter()
8183
resolve()
8284
}).catch(error => {
8385
reject(error)
@@ -95,22 +97,25 @@ const actions = {
9597
})
9698
},
9799

98-
// 动态修改权限
100+
// Dynamically modify permissions
99101
changeRoles({ commit, dispatch }, role) {
100-
return new Promise(resolve => {
102+
return new Promise(async resolve => {
101103
const token = role + '-token'
104+
102105
commit('SET_TOKEN', token)
103106
setToken(token)
104-
getInfo(token).then(response => {
105-
const { data } = response
106-
const { roles, name, avatar, introduction } = data
107-
commit('SET_ROLES', roles)
108-
commit('SET_NAME', name)
109-
commit('SET_AVATAR', avatar)
110-
commit('SET_INTRODUCTION', introduction)
111-
dispatch('permission/generateRoutes', data) // 动态修改权限后 重绘侧边菜单
112-
resolve()
113-
})
107+
108+
const { roles } = await dispatch('getInfo')
109+
110+
resetRouter()
111+
112+
// generate accessible routes map based on roles
113+
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
114+
115+
// dynamically add accessible routes
116+
router.addRoutes(accessRoutes)
117+
118+
resolve()
114119
})
115120
}
116121
}

src/views/login/index.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,14 @@ export default {
135135
this.$refs.loginForm.validate(valid => {
136136
if (valid) {
137137
this.loading = true
138-
// dispatch @/store/modules/user login action
139-
this.$store.dispatch('user/login', this.loginForm).then(() => {
140-
this.loading = false
141-
this.$router.push({ path: this.redirect || '/' })
142-
}).catch(() => {
143-
this.loading = false
144-
})
138+
this.$store.dispatch('user/login', this.loginForm)
139+
.then(() => {
140+
this.$router.push({ path: this.redirect || '/' })
141+
this.loading = false
142+
})
143+
.catch(() => {
144+
this.loading = false
145+
})
145146
} else {
146147
console.log('error submit!!')
147148
return false

0 commit comments

Comments
 (0)