vue-admin logon rights and routing guard

Use vue development of back office systems, in addition to routing and page set up, as well as the main logon permissions and routing guard. Since vue-admin-element back office systems used directly, which has done administrative login privileges, the record is for the better sort out the process for their own projects, as well as subsequent viewing and supplements.

vue-admin-element module Address: https://github.com/PanJiaChen/vue-element-admin

vue-admin-element template Introduction: https://segmentfault.com/a/1190000009275424

 

About Project Files

Here first introduce the list of related documents to facilitate the subsequent path view (mainly marked red)

├── build // build-related   
├── config // configuration-related 
├── src // source code 
│ ├── api // All requests 
│ ├── assets // theme font and other static resources 
│ ├── components // global common components 
│ ├── directive // global Order 
│ ├── filtres // global filter 
│ ├── iconsThe // project iconsThe all SVG 
│ ├── lang // internationalization Language 
│ ├── mock / / project mock simulation data 
│ ├── Router                  // routing 
│ ├── store                   // global store management 
│ ├── styles // global style 
│ ├──utils                   // global public method 
│ ├── vendor // public Vendor 
│ ├── // View page views 
│ ├── App.vue // entry page 
│ ├── main.js // initialization inlet loading assembly 
│ └── permission.js           // rights management 
├── static // third-party resources are not packaged 
│ └── Tinymce // rich text 
├── .babelrc // babel-loader configuration 
├── eslintrc.js // eslint configuration item 
├── .gitignore // git ignore items 
├── favicon.ico // favicon icon 
├── index.html // html template 
└── package.json // package.json

1, the first is to log into the system function, is used here vuex management login information and user information

Page path: src / views / login / index
  // Log 
  handleLogin () {
    // verification was this. $ Refs.loginForm.validate (Valid => { IF (Valid) {
      // login methods directed Login src / store / modules / user.js in this. $ store.dispatch ( 'Login', this.loginForm) .then (() => {
       // Direction and routing Home Login to the this $ router.push ({path:. '/'}) }). the catch (( ) => { }) } {the else the console.log ( 'Submit error !!') return to false } }) },

2, manage log on and access to user information

Page path: src / store / modules / user.js
  // log 
    the Login ({} the commit, the userInfo) { 
      const userInfo.username.trim username = () // The empty 
      const fd = new FormData () // login parameters 
      fd.append ( 'username', username) 
      fd.append ( 'password', userInfo.password) 
      return new new Promise ((Resolve, Reject) => { 
        Login (FD) .then (Response => { 
          const = Data response.data 
          setToken (data.token) // store token information 
          commit ( 'SET_TOKEN', data.access_token) 
          Resolve () 
        }). the catch (error => { 
          // the console.log (. 5) 
          Reject (error) 
        }) 
      }) 
    }, 

  // obtain user information
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(response => {
          const data = response.data
      //获取用户权限并存储roles if (data.roles && data.roles.length > 0) { commit('SET_ROLES', data.roles) } else { reject('getInfo: roles must be a non-null array !') } commit('SET_USERNAME', data.username) commit('SET_NICKNAME', data.nickname) resolve(response) }).catch(error => { reject(error) }) }) },

3, intercepted request

Page path: src / utils / request.js
Axios from Import 'Axios' 
// Import from QS "QS" 
Import {} from the Message 'UI-Element' 
Import from Store '../store' 
Import getToken to {} from '@ / utils / the auth' 
Import} from {apiURL '@ / API / config / IP-config' 
// Create instance axios 
const = axios.create-Service ({ 
  the baseURL: process.env.BASE_API, // API of the base_url 
  timeout: 15000 // request time 
}) 
// request interceptor 
service.interceptors.request.use ( 
  config => { 
    IF (getToken to ()) { 
    // if the token is present, to bring .x-token token information request header in each of their key is defined, with the end negotiation unified config.headers [ 'X--token'] = getToken to () } return config }, error =>{ // Do something with request error // console.log(error) // for debug Promise.reject(error) } ) // respone拦截器 service.interceptors.response.use( (response) => {
    /**
    * Custom code to mark the status of the request
    * When the code returns the following cases it indicates a problem with authority, log out and return to the login page
    * To xmlhttprequest identified by status codes, error logic can be written in the following
    */
    response.data RES = const 
    IF (res.code) { 
    // custom status code 1000 is valid, values other special status, may be incorporated to modify their business IF (res.code! == 1000) { the Message ({ Message : res.message, of the type: 'error', DURATION: 5 * 1000 }) // 50008: illegal token; 50012: other clients logged; 50014: token expired; // IF (res.code === res.code === || 50012 || 50008 res.code === 50014) { // MessageBox.confirm ( // 'you have been logged out, you can cancel to stay on this page, or log in again', / / 'OK sign out', // { // confirmButtonText: 're-login', // cancelButtonText: 'cancel', // of the type: 'warning' // } // ).then(() => { // store.dispatch('FedLogOut').then(() => { // location.reload() // 为了重新实例化vue-router对象 避免bug // }) // }) // } return Promise.reject('error') } else { return response.data } } else { return response } // return response }, error => { if (typeof (error.response) !== 'undefined') { if (error.response.status === 401) { // MessageBox.alert(error.response.data.message, '提示', { // confirmButtonText:'re-register', // type: 'warning' // }) Message({ message: error.response.data.message, type: 'info', duration: 5 * 1000 }) setTimeout(function() { store.dispatch('FedLogOut').then(() => { location.reload()// 为了重新实例化vue-router对象 避免bug }) }, 1000) // .then(() => { // }) } else { Message({ message: error.response.data.message, type: 'error', duration: 5 * 1000 }) } } else { Message({ message: error.message, type: 'error', duration: 5 * 1000 }) } return Promise.reject(error) } ) export default service

4, set up routing

Page path: src / router / index.js
import Vue from 'vue'
import Router from 'vue-router'

// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading

Vue.use(Router)

/* Layout */
import Layout from '../views/layout/Layout'

/**
* hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
* alwaysShow: true               if set true, will always show the root menu, whatever its child routes length
*                                if not set alwaysShow, only more than one route under the children
*                                it will becomes nested mode, otherwise not show the root menu
* redirect: noredirect           if `redirect:noredirect` will no redirct in the breadcrumb
* name:'router-name'             the name is used by <keep-alive> (must set!!!)
* meta : {
    title: 'title'               the name show in submenu and breadcrumb (recommend set)
    icon: 'svg-name'             the icon show in the sidebar,
  }
**/
export const constantRouterMap = [
  // 基础-路由设置
  { path: '/login', component: () => import('@/views/login/index'), hidden: true },
  { path: '/404', component: () => import('@/views/404'), hidden: true },
  // { path: '*', redirect: '/404', hidden: true },
  {
    path: '',
    component: Layout,
    redirect: 'home',
    children: [{
      path: 'home',
      component: () => import('@/views/home/index'),
      name: 'home',
      meta: { title: '首页', icon: 'table', noCache: true }
    }]
  }
]

export const asyncRouterMap = [
{
  path: '/demo',
  component: Layout,
  redirect: '/demo/demoChild1',
  alwaysShow: true, // will always show the root menu
  name: 'Demo',
  meta: {
    title: '示例',
    icon: 'tree',
    roles: ['admin','demoRoles']
  },
  Children: [
    {
      path: 'demoChild1',
      Component: () => Import ( '@ / views / Demo / demoChild1'),
      name: 'DemoChild1',
      Meta: {
        title: 'example a C1'
      }
    },
    {
      path: 'demoChild2',
      Component: () => Import ( '@ / views / Demo / demoChild2'),
      name: 'DemoChild2',
      Meta: {
        title: 'example C2'
      }
    }
  ]
},
{path: '* ', redirect:' / 404 ' , hidden: true} // very important, if dynamic routing, be sure to define the last 404 pages, the page could not be matched to prevent error
]
//重置路由
const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRouterMap.concat(asyncRouterMap)
  // routes: []
})
const router = createRouter()
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router

 

5, filter routing

  If the menu bar is dead then write the front end without considering this step.

  But we are doing backstage management system, they usually are under the authority of the logged in user have to show a different menu bar.

  So to match the appropriate route is particularly important.

 Page path: src / store / permission.js
  
{asyncRouterMap Import, from constantRouterMap} '@ / Router' 
/ ** 
* asyncRouterMap incorporated with constantRouterMap src / router / index defined
* constantRounterMap: General route based write / login, / 404, etc.
* asyncRouterMap: writing must be configured to route and the management roles / ** * matches meta.role determined by the current user rights * @param roles * @param route * / function the hasPermission (roles, route) { iF (route.meta && route.meta.roles) { return roles.some (role => route.meta.roles.indexOf (role)> = 0) } the else { return to true } } / ** * recursive filter asynchronous routing table, in line with the user role privileges returns routing table * @ asyncRouterMap param * @param the Roles * / function filterAsyncRouter(asyncRouterMap, roles) { const accessedRouters = asyncRouterMap.filter(route => { if (hasPermission(roles, route)) { if (route.children && route.children.length) { route.children = filterAsyncRouter(route.children, roles) } return true } return false }) return accessedRouters } const permission = { state: { routers: constantRouterMap, addRouters: [] }, mutations: { SET_ROUTERS: (state, routers) => { state.addRouters = routers state.routers = constantRouterMap.concat(routers) } }, Actions: { generateRoutes (the commit {}, Data) { return new new Promise (Resolve => { const} = {Data Roles the let accessedRouters = []
     // herein may be adjusted according to business needs, the present project has admin All rights IF (roles.indexOf ( 'ADMIN')> = 0) { accessedRouters = asyncRouterMap } the else { accessedRouters = filterAsyncRouter (asyncRouterMap, Roles) } the commit ( 'SET_ROUTERS', accessedRouters) Resolve () }) } } } Export default permission

6, routing and routing guard intercepted

  After we get the user roles, through router.addRoutesdynamic routing mount

  Page path: src / permission.js
Router from Import './router' 
Import from Store './store' Import from nProgress' nProgress' Progress progress bar // import 'nprogress / nprogress.css' // Progress progress bar style import {Message} from' element- ui ' Import} {getToken from' @ / utils / auth 'experience // right // filter qualifying route - can be adjusted according to their own business - according to the parameter information to make the determination, if eligible, then go to the appropriate page, or go to 404 function the hasPermission (Roles, to) { IF (roles.indexOf ( 'ADMIN')> = 0) { return to true // permission ADMIN passed Directly } IF (to.meta.roles) { return roles.some (Role => to.meta.roles.indexOf (Role)> = 0) } the else { return to true } } const WhiteList = [ '/ Login', '/ 404 '] // not redirected whitelist router.beforeEach ((to, from, Next) => { NProgress.start () IF (getToken to ()) {
  // routing guard IF (to.path === '/ Login') { Next ({path: ' / '}) NProgress.done () // IF Current Page iS Dashboard Will Not Trigger afterEach Hook, SO IT Manually handle } the else { IF (store.getters.roles.length === 0) {
     // If the permission roles as empty, then retrieve user information, update Roles store.dispatch ( 'the GetInfo'). the then (RES => {// user information pulling const = Roles res.data.roles store.dispatch ( 'generateRoutes', {} Roles ) .then (() => { // the roles access rights generated routing table router.addRoutes (store.getters.addRouters) // add dynamic routing table accessible next ({... to, replace: true}) // hack method ensures addRoutes has been completed, The SET Replace: The SO to true Navigation History Record Will Not Leave A }) .}) the catch ((ERR) => { Store .dispatch ( 'FedLogOut') the then (() => {. Message.Error An (ERR || 'the Verification failed, Please Login Again') Next ({path: '/'}) }) }) } the else {
     // If there is already permission, filtered eligible routes, if not, then skip to page 404
     // here hasPermission roles is to verify compliance, which is a parameter to the page you want to jump to the route-related information, can be modified according to their business
if (the hasPermission (store.getters.roles, to)) { Next () // } the else { Next ({path: '/ 404', Replace: to true, Query: {noGoBack: to true}}) } } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next('/login') NProgress.done() } } }) router.afterEach(() => { NProgress.done() // 结束Progress })

 At this point, log on vue-admin privileges and basic these, of course, there are many other ways, this is only required for the current project, and then continue to follow a perfect complement.

For more information about vue-admin-element can be found here: vue-admin-element template description: https://segmentfault.com/a/1190000009275424 .

Guess you like

Origin www.cnblogs.com/liangpi/p/11906207.html