Skip to content
This repository was archived by the owner on May 12, 2020. It is now read-only.

Commit d62063d

Browse files
committed
feat(access): implement access aproach
1 parent ea55a85 commit d62063d

17 files changed

Lines changed: 189 additions & 37 deletions

File tree

src/api/index.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ export function userLogin ({
1111
})
1212
}
1313

14+
export function fetchUserAccess ({ username }) {
15+
return request.post(routes.ACCESS, {
16+
username
17+
})
18+
}
19+
1420
export function fetchDynamicRoutes ({
15-
username,
16-
accessToken
21+
username
1722
}) {
1823
return request.post(routes.DYNAMIC_ROUTES, {
19-
username,
20-
accessToken
24+
username
2125
})
2226
}

src/api/routes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export default {
22
LOGIN: '/user/login',
3+
ACCESS: '/user/access',
34
DYNAMIC_ROUTES: '/user/access'
45
}

src/components/RouteExport.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
render (h) {
3+
return h('router-view', {
4+
class: 'router-export'
5+
})
6+
}
7+
}

src/layout/Material/Header.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
<el-button
88
class="logout"
99
type="text"
10-
@click="$router.push('/pages/admin/dashboard')"
10+
@click="$router.push('/admin/dashboard')"
1111
>dashboard</el-button>
1212
<el-button
1313
class="logout"
1414
type="text"
15-
@click="$router.push('/pages/admin/table')"
15+
@click="$router.push('/admin/table')"
1616
>table</el-button>
1717
<el-button
1818
class="logout"
1919
type="text"
20-
@click="$router.push('/pages/common/user')"
20+
@click="$router.push('/common/user')"
2121
>user info</el-button>
2222
<el-button
2323
class="logout"

src/pages/Access/index.vue

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<section class="access__static">
3+
this is static route for {{$route.meta.role}} role.
4+
</section>
5+
</template>
6+
7+
<script>
8+
export default {
9+
}
10+
</script>
11+
12+
<style lang='scss' scoped>
13+
</style>

src/pages/NotFound/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
name: 'NotFound',
3+
render (h) {
4+
return h('section', {
5+
class: 'not-found'
6+
},
7+
'Seems nothing could found.')
8+
}
9+
}

src/permission/index.js

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,39 @@ router.beforeEach((to, from, next) => {
1818
NProgress.start()
1919

2020
// Jump to target path directly If target path has been included by white list
21+
// or common routes
22+
// if (WHITELIST.includes(to.path) || !to.meta.roles) {
2123
if (WHITELIST.includes(to.path)) {
22-
next()
23-
return
24+
return next()
2425
}
2526

26-
// fetching user private routes
27-
if (getTokenFromLocal()) { // User has been logged in
28-
if (
29-
!store.state.login.dynamicRoutes.length ||
30-
!store.state.login.dynamicRoutes[0].component
31-
) {
32-
store.dispatch('login/fetchDynamicRoutes')
33-
.then(routes => store.dispatch('login/createGlobalRoutes', routes))
34-
.catch(e => {
35-
MessageBox({
36-
title: 'Error',
37-
message: 'We got a error when fetching user access.',
38-
type: 'error',
39-
showClose: false
40-
})
41-
.then(() => store.dispatch('login/userLogout'))
42-
.then(() => next({
43-
path: `/login?redirect=${to.path}`,
44-
replace: true
45-
}))
46-
NProgress.done()
47-
console.error(e)
48-
})
27+
// ! State: User has been logged in.
28+
if (getTokenFromLocal()) {
29+
// 1. fetch rolesMap if necessary (when rolesMap stored by back-end)
30+
31+
// 2. confirm route access by user role
32+
if (!store.getters['login/role']) {
33+
// 2.1 No roles: fetch user role
34+
return store.dispatch(
35+
'login/fetchUserAccess',
36+
store.getters['login/username']
37+
)
38+
.catch(e => errorHandler(e, next, to.path))
39+
.finally(() => next())
40+
}
41+
42+
// 2.2 filter route
43+
if (!to.meta.roles ||
44+
to.meta.roles.includes(store.getters['login/role'][0])) {
45+
next()
46+
} else {
47+
next({
48+
path: `/403?redirect=${to.path}`,
49+
replace: true
50+
})
4951
}
50-
next()
5152
} else {
53+
// ! State: user logout
5254
next({
5355
path: `/login?redirect=${to.path}`,
5456
replace: true
@@ -61,3 +63,19 @@ router.afterEach((to, from) => {
6163
})
6264

6365
export default router
66+
67+
function errorHandler (e, next, redirectPath) {
68+
MessageBox({
69+
title: 'Error',
70+
message: 'We got a error when fetching user access.',
71+
type: 'error',
72+
showClose: false
73+
})
74+
.then(() => store.dispatch('login/userLogout'))
75+
.then(() => next({
76+
path: `/login?redirect=${redirectPath}`,
77+
replace: true
78+
}))
79+
NProgress.done()
80+
console.error(e)
81+
}

src/permission/rolesMap.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* This map can be stored by back-end, rather than front-end for implement
3+
* real-time route access edit.
4+
*/
5+
export default {
6+
admin: {
7+
dashboard: ['sudo', 'admin'],
8+
table: ['sudo', 'admin']
9+
},
10+
access: {
11+
admin: ['super admin', 'admin'],
12+
user: ['user']
13+
}
14+
}

src/router/components/constant.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// ! constant component path, based on `/src` directory
22
export default [
3+
'pages/Access',
34
'pages/Home',
4-
'pages/Login'
5+
'pages/Admin/Dashboard',
6+
'pages/Admin/Table',
7+
'pages/Common/User',
8+
'pages/Login',
9+
'pages/NotFound'
510
]

src/router/index.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import Vue from 'vue'
22
import Router from 'vue-router'
33
import { constantComponents } from './components'
4+
import permission from 'PERMISSION/rolesMap'
5+
6+
const plainExport = () => import('COMPONENTS/RouteExport')
47

58
Vue.use(Router)
69

10+
console.log('constantComponents :', constantComponents)
11+
712
export const constantRoutes = [
813
{
914
path: '/',
@@ -21,6 +26,65 @@ export const constantRoutes = [
2126
meta: {
2227
layout: 'plain'
2328
}
29+
},
30+
{
31+
path: '/admin',
32+
component: plainExport,
33+
children: [
34+
{
35+
path: 'dashboard',
36+
component: constantComponents.pagesAdminDashboard,
37+
meta: {
38+
roles: permission.admin.dashboard
39+
}
40+
},
41+
{
42+
path: 'table',
43+
component: constantComponents.pagesAdminTable,
44+
meta: {
45+
roles: permission.admin.table
46+
}
47+
}
48+
]
49+
},
50+
{
51+
path: '/common',
52+
component: plainExport,
53+
children: [
54+
{
55+
path: 'user',
56+
component: constantComponents.pagesCommonUser
57+
}
58+
]
59+
},
60+
{
61+
path: '/access',
62+
name: 'access',
63+
component: plainExport,
64+
children: [
65+
{
66+
path: 'admin',
67+
component: constantComponents.pagesAccess,
68+
meta: {
69+
roles: permission.access.admin
70+
}
71+
},
72+
{
73+
path: 'user',
74+
component: constantComponents.pagesAccess,
75+
meta: {
76+
roles: permission.access.user
77+
}
78+
}
79+
]
80+
},
81+
{
82+
path: '/404',
83+
component: constantComponents.pagesNotFound
84+
},
85+
{
86+
path: '*',
87+
redirect: '/404'
2488
}
2589
]
2690

0 commit comments

Comments
 (0)