A front-end access control solution building with Vue.js v2.6+
-
Dynamic aside rendering
All of console aside menu items is based on current user global routes which is made of public routes and private routes
-
Public routes means their generation will be ignored by access verification process.
-
Private routes means these routes are filtered by current user access.
-
-
The implement of mandatory access control and optional access control
You can set up two typical solutions for access verification.
-
Mandatory access control, current user access should be satisfied all of them, otherwise routes wouldn't be created.
-
Optional access control, private routes will be create when current user access just matched one of them
-
-
User access console which is used to distribute access to user.
-
Dynamic component importer.
Just edit your own component path based on
{PROJECT_ROOT}/src
in the{PROJECT_ROOT}/src/router/components
directory.// It will use `() => import(...)` function to import your component dynamically export default ['page/someComponent']
then you can import component like these code:
import { privateComponents } from 'ROUTER/components' export default [ { path: '/private', component: privateComponents.pageSomeComponent } ]
-
User access schema, you can store it anywhere (eg, local environment or remote database).
/** * @description These access set can be store anywhere you want. * You should fetch all current access before you activate * private routes generation. */ interface UserAccess { access: string update_time: string [extraMeta: string]: any } type UserAccessSet = UserAccess[]
The most important thing is in
access
field ofUserAccess
scheme. We will use this field to create current user access map which is used to implement front-end access control and aside menu rendering dynamically. -
Route schema, inherited from route schema of
vue-router
interface Route extends RouteOfVueRouter { meta: { title: string icon: string layout: string access?: string[] optionalAccess?: string[] } }
Field description title Used to create a title in the aside menu icon Used to create a icon for above title layout Used to create a layout for route linked with above title access Used to determine mandatory access for current route optionalAccess Used to determine optional access for current route
-
Routes-access control
export default [ { path: '/fist-routes', components: firstComponent, meta: { /** * @description This route will be added to global routes map if user * accesses include 'device.read' and 'device.write' access. */ access: ['admin.device.read', 'admin.device.write'] } }, { path: '/second-routes', components: secondComponent, meta: { /** * @description Current route will be ignored when current user has no 'mange.device.write' access */ access: ['admin.device.read', 'admin.device.write'] } }, { path: '/optional-routes', components: optionalComponent, meta: { /** * @description Once one of access was matched, private routes will be created. */ optionalAccess: ['admin.device.read', 'admin.device.write'] } } // ... other routes ]
meta field | description |
---|---|
access | Current user's access list should include all items of access field. |
optionalAccess | Current user's access list include at least one access of optionalAccess field. |
-
Element-access control
-
Single access control
<!-- Element will be disappeared when user has no 'admin.device.read' access --> <AnyElement v-access="admin.device.read" /> <AnyElement v-if="$_hasAccess('admin.device.read')" />
-
Optional access control
<!-- The current user's accesses should include at least one of the target access list. --> <AnyElement v-access.some="['admin.device.read', 'admin.device.write']" /> <AnyElement v-if="$_hasSomeAccess(['admin.device.read', 'admin.device.write'])" />
-
Mandatory access control
<!-- The current user's accesses should include all accesses in the target access list. --> <AnyElement v-access.every="['admin.device.read', 'admin.device.write']" /> <AnyElement v-if="$_hasEveryAccess(['admin.device.read', 'admin.device.write'])" />
-
As you wish, you can use Vue
prototype function $_hasAccess
, $_hasSomeAccess
, $_hasEveryAccess
to verify any user access without limitation.
NOTICE: You should use
parent.$_hasAccess
to verify user access in the Vue functional component which has a non-functional parent vue component.
Vue v-access directive with modifiers |
description |
---|---|
v-access |
Single access verification |
v-access.some |
Optional access verification |
v-access.every |
Mandatory access control |
Vue prototype function | description |
---|---|
$_hasAccess |
Single access verification |
$_hasSomeAccess |
Optional access verification |
$_hasEveryAccess |
Mandatory access control |
- Compiles and hot-reloads for development
yarn run serve
- Compiles and minifies for production
yarn run build
CHANGELOG is here.