Skip to content

Commit af3c7c2

Browse files
committed
add auth module
1 parent ea60478 commit af3c7c2

File tree

10 files changed

+108
-42
lines changed

10 files changed

+108
-42
lines changed

mock/user.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ const tokens = {
1111
const users = {
1212
'admin-token': {
1313
roles: ['admin'],
14+
auths: [
15+
'icon:view', 'example:view'
16+
],
1417
introduction: 'I am a super administrator',
1518
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
1619
name: 'Super Admin'
1720
},
1821
'editor-token': {
1922
roles: ['editor'],
23+
auths: [],
2024
introduction: 'I am an editor',
2125
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
2226
name: 'Normal Editor'

src/directive/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import checkAuth from '@/utils/permission'
2+
3+
export default (Vue) => {
4+
Vue.directive('auth', {
5+
inserted: (el, binding) => {
6+
if (!checkAuth(binding.value)) {
7+
el.remove()
8+
}
9+
}
10+
})
11+
Vue.directive('auth-all', {
12+
inserted: (el, binding) => {
13+
if (!checkAuth(binding.value, true)) {
14+
el.remove()
15+
}
16+
}
17+
})
18+
}

src/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import './utils/error-log' // error log
2020

2121
import * as filters from './filters' // global filters
2222

23+
import directive from '@/directive/index.js'
24+
Vue.use(directive)
2325
/**
2426
* If you don't want to use mock-server
2527
* you want to use MockJs for mock api

src/permission.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ router.beforeEach(async(to, from, next) => {
2727
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
2828
} else {
2929
// determine whether the user has obtained his permission roles through getInfo
30-
const hasRoles = store.getters.roles && store.getters.roles.length > 0
31-
if (hasRoles) {
30+
const hasAuths = store.getters.auths && store.getters.roles.length > 0
31+
if (hasAuths) {
3232
next()
3333
} else {
3434
try {
3535
// get user info
3636
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
37-
const { roles } = await store.dispatch('user/getInfo')
37+
const { auths } = await store.dispatch('user/getInfo')
3838

3939
// generate accessible routes map based on roles
40-
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
40+
const accessRoutes = await store.dispatch('permission/generateRoutes', auths)
4141

4242
// dynamically add accessible routes
4343
router.addRoutes(accessRoutes)

src/router/index.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ export const asyncRoutes = [
137137
name: 'Permission',
138138
meta: {
139139
title: 'Permission',
140-
icon: 'lock',
141-
roles: ['admin', 'editor'] // you can set roles in root nav
140+
icon: 'lock'
142141
},
143142
children: [
144143
{
@@ -197,14 +196,16 @@ export const asyncRoutes = [
197196
name: 'Example',
198197
meta: {
199198
title: 'Example',
200-
icon: 'el-icon-s-help'
199+
icon: 'el-icon-s-help',
200+
auth: ['example:view']
201201
},
202+
alwaysShow: true,
202203
children: [
203204
{
204205
path: 'create',
205206
component: () => import('@/views/example/create'),
206207
name: 'CreateArticle',
207-
meta: { title: 'Create Article', icon: 'edit' }
208+
meta: { title: 'Create Article', icon: 'edit', auth: ['example:add'] }
208209
},
209210
{
210211
path: 'edit/:id(\\d+)',
@@ -217,7 +218,7 @@ export const asyncRoutes = [
217218
path: 'list',
218219
component: () => import('@/views/example/list'),
219220
name: 'ArticleList',
220-
meta: { title: 'Article List', icon: 'list' }
221+
meta: { title: 'Article List', icon: 'list', auth: ['example:view'] }
221222
}
222223
]
223224
},

src/store/getters.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ const getters = {
99
name: state => state.user.name,
1010
introduction: state => state.user.introduction,
1111
roles: state => state.user.roles,
12+
auths: state => state.user.auths,
1213
permission_routes: state => state.permission.routes,
13-
errorLogs: state => state.errorLog.logs
14+
errorLogs: state => state.errorLog.logs,
15+
hasAuthorization: state => authorization => {
16+
return state.authorization.some(auth => {
17+
return auth === authorization
18+
})
19+
}
1420
}
1521
export default getters

src/store/modules/permission.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,21 @@ import { asyncRoutes, constantRoutes } from '@/router'
55
* @param roles
66
* @param route
77
*/
8-
function hasPermission(roles, route) {
9-
if (route.meta && route.meta.roles) {
10-
return roles.some(role => route.meta.roles.includes(role))
8+
// function hasPermission(roles, route) {
9+
// if (route.meta && route.meta.roles) {
10+
// return roles.some(role => route.meta.roles.includes(role))
11+
// } else {
12+
// return true
13+
// }
14+
// }
15+
16+
function hasAuthorization(authorization, route) {
17+
if (route.meta && route.meta.auth) {
18+
return authorization.some(auth => {
19+
return route.meta.auth.some(routeAuth => {
20+
return routeAuth === auth
21+
})
22+
})
1123
} else {
1224
return true
1325
}
@@ -18,14 +30,14 @@ function hasPermission(roles, route) {
1830
* @param routes asyncRoutes
1931
* @param roles
2032
*/
21-
export function filterAsyncRoutes(routes, roles) {
33+
export function filterAsyncRoutes(routes, auths) {
2234
const res = []
2335

2436
routes.forEach(route => {
2537
const tmp = { ...route }
26-
if (hasPermission(roles, tmp)) {
38+
if (hasAuthorization(auths, tmp)) {
2739
if (tmp.children) {
28-
tmp.children = filterAsyncRoutes(tmp.children, roles)
40+
tmp.children = filterAsyncRoutes(tmp.children, auths)
2941
}
3042
res.push(tmp)
3143
}
@@ -47,14 +59,10 @@ const mutations = {
4759
}
4860

4961
const actions = {
50-
generateRoutes({ commit }, roles) {
62+
generateRoutes({ commit }, auths) {
63+
console.log(auths)
5164
return new Promise(resolve => {
52-
let accessedRoutes
53-
if (roles.includes('admin')) {
54-
accessedRoutes = asyncRoutes || []
55-
} else {
56-
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
57-
}
65+
const accessedRoutes = filterAsyncRoutes(asyncRoutes, auths)
5866
commit('SET_ROUTES', accessedRoutes)
5967
resolve(accessedRoutes)
6068
})

src/store/modules/user.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const state = {
77
name: '',
88
avatar: '',
99
introduction: '',
10-
roles: []
10+
roles: [],
11+
auths: []
1112
}
1213

1314
const mutations = {
@@ -25,6 +26,9 @@ const mutations = {
2526
},
2627
SET_ROLES: (state, roles) => {
2728
state.roles = roles
29+
},
30+
SET_AUTHS: (state, auths) => {
31+
state.auths = auths
2832
}
2933
}
3034

@@ -54,14 +58,15 @@ const actions = {
5458
reject('Verification failed, please Login again.')
5559
}
5660

57-
const { roles, name, avatar, introduction } = data
61+
const { roles, auths, name, avatar, introduction } = data
5862

5963
// roles must be a non-empty array
60-
if (!roles || roles.length <= 0) {
61-
reject('getInfo: roles must be a non-null array!')
64+
if (!auths || auths.length <= 0) {
65+
reject('getInfo: auths must be a non-null array!')
6266
}
6367

6468
commit('SET_ROLES', roles)
69+
commit('SET_AUTHS', auths)
6570
commit('SET_NAME', name)
6671
commit('SET_AVATAR', avatar)
6772
commit('SET_INTRODUCTION', introduction)
@@ -78,6 +83,7 @@ const actions = {
7883
logout(state.token).then(() => {
7984
commit('SET_TOKEN', '')
8085
commit('SET_ROLES', [])
86+
commit('SET_AUTHS', [])
8187
removeToken()
8288
resetRouter()
8389

@@ -97,6 +103,7 @@ const actions = {
97103
return new Promise(resolve => {
98104
commit('SET_TOKEN', '')
99105
commit('SET_ROLES', [])
106+
commit('SET_AUTHS', [])
100107
removeToken()
101108
resolve()
102109
})

src/utils/permission.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,25 @@ import store from '@/store'
55
* @returns {Boolean}
66
* @example see @/views/permission/directive.vue
77
*/
8-
export default function checkPermission(value) {
9-
if (value && value instanceof Array && value.length > 0) {
10-
const roles = store.getters && store.getters.roles
11-
const permissionRoles = value
12-
13-
const hasPermission = roles.some(role => {
14-
return permissionRoles.includes(role)
15-
})
16-
return hasPermission
8+
export default function checkAuth(value, checkAll) {
9+
if (typeof checkAll === 'undefined') {
10+
checkAll = false
11+
}
12+
const hasAuthorization = store.getters.hasAuthorization
13+
if (typeof value === 'string') {
14+
return hasAuthorization(value)
15+
} else if (value && value instanceof Array && value.length > 0) {
16+
if (checkAll) {
17+
return value.every(auth => {
18+
return hasAuthorization(auth)
19+
})
20+
} else {
21+
return value.some(auth => {
22+
return hasAuthorization(auth)
23+
})
24+
}
1725
} else {
18-
console.error(`need roles! Like v-permission="['admin','editor']"`)
26+
console.error(`need auths! Like v-auths="['admin','editor']"`)
1927
return false
2028
}
2129
}

src/utils/request.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ service.interceptors.request.use(
1919
// let each request carry token
2020
// ['X-Token'] is a custom headers key
2121
// please modify it according to the actual situation
22+
// config.headers['Authorization'] = 'Bearer ' + getToken()
2223
config.headers['X-Token'] = getToken()
2324
}
2425
return config
@@ -73,11 +74,22 @@ service.interceptors.response.use(
7374
},
7475
error => {
7576
console.log('err' + error) // for debug
76-
Message({
77-
message: error.message,
78-
type: 'error',
79-
duration: 5 * 1000
80-
})
77+
if (error && error.response && error.response.status === 401) {
78+
Message({
79+
message: error.response.data.message,
80+
type: 'error',
81+
duration: 5 * 1000
82+
})
83+
store.dispatch('user/resetToken').then(() => {
84+
location.reload()
85+
})
86+
} else {
87+
Message({
88+
message: error.message,
89+
type: 'error',
90+
duration: 5 * 1000
91+
})
92+
}
8193
return Promise.reject(error)
8294
}
8395
)

0 commit comments

Comments
 (0)