Analysis and implementation of routing and permission verification in Element UI

1. Routing and permission verification

  1. Routing and permission verification, how to deal with routing and permission mapping in participating projects?
  2. The routing processing logic analysis is as follows:
  • Access /xxx, router.beforeEachwill make the global navigation guard, from cookieacquiring the tokenjudge tokenis present.
  • If tokennot present, it is determined whether the route of the whitelist. If it is in the whitelist, access the route /xxx. If it is not in the whitelist, access the route /login?redirect=/xxx.
  • If tokenthere is, it determines whether the route /login. If the route is yes /login, then redirect to /. If the route is not /login, get the user's role, dynamically generate the route, and replaceaccess the route in a pattern /xxx. If an abnormal situation occurs, reset it tokenand visit the router /login?redirect=/xxx.
  1. Analysis of routing scenarios, common in middle and back-end routing, are as follows:
  • Obtained token:
    • Visit /login, redirect to/
    • Visit /login?redirect=/xxx, redirect to/xxx
    • Access /loginroutes other than direct access/xxx
  • Not obtained token:
    • Access /login, direct access/login
    • Access /loginroutes other than such as access /dashboard, access path for the real /login?redirect=%2Fdashboard, will sign redirected to/dashboard

Second, the realization of routing and permission verification

  1. The global navigation guard router.beforeEach in permission.js , the code is as follows:
// 定义了全局导航路由守卫
router.beforeEach(async(to, from, next) => {
    
    
  // 显示的进度条,启动进度条
  NProgress.start()

  // 修改页面标题
  document.title = getPageTitle(to.meta.title)

  // 从 Cookie 中获取 Token
  const hasToken = getToken()

  // 判断 Token 是否存在
  if (hasToken) {
    
     // Token 存在
    // 如果当前路径为 login 则直接重定向到首页
    if (to.path === '/login') {
    
    
      // if is logged in, redirect to the home page
      next({
    
     path: '/' })
      NProgress.done()
    } else {
    
    
      // 判读用户的角色是否存在
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      // 如果用户角色存在,则直接访问
      if (hasRoles) {
    
    
        next()
      } else {
    
    
        try {
    
    
          // 异步获取用户的角色
          const {
    
     roles } = await store.dispatch('user/getInfo')

          // 根据用户的角色,动态生成路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)

          // 调用 router.addRoutes 动态添加路由
          router.addRoutes(accessRoutes)

          // 使用 replace 访问路由,不会在 history 中留下记录
          next({
    
     ...to, replace: true })
        } catch (error) {
    
    
          // 移除 Token 数据
          await store.dispatch('user/resetToken')
          // 显示错误提示
          Message.error(error || 'Has Error')
          // 重定向到登录页面
          next(`/login?redirect=${
      
      to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    
     // Token不存在
    // 如果访问的 URL 在白名单中,则直接访问
    if (whiteList.indexOf(to.path) !== -1) {
    
    
      next()
    } else {
    
    
      // 如果访问的 URL 不在白名单中,则直接重定向到登录页面,并将访问的 URL 添加到 redirect 中
      next(`/login?redirect=${
      
      to.path}`)
      NProgress.done()
    }
  }
})
  1. permission.js , the complete code is as follows:
import router from './router'
import store from './store'
import {
    
     Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import {
    
     getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

// 让显示的进度条隐藏,旋转的
// showSpinner 可以控制右侧的环形进度条是否显示
NProgress.configure({
    
     showSpinner: false }) 

// 白名单
const whiteList = ['/login', '/auth-redirect'] 
// 定义了全局导航路由守卫
router.beforeEach(async(to, from, next) => {
    
    
  // 显示的进度条,启动进度条
  NProgress.start()

  // 修改页面标题
  document.title = getPageTitle(to.meta.title)

  // 从 Cookie 中获取 Token
  const hasToken = getToken()

  // 判断 Token 是否存在
  if (hasToken) {
    
    
    // 如果当前路径为 login 则直接重定向到首页
    if (to.path === '/login') {
    
    
      next({
    
     path: '/' })
      NProgress.done()
    } else {
    
    
      // 判读用户的角色是否存在
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      // 如果用户角色存在,则直接访问
      if (hasRoles) {
    
    
        next()
      } else {
    
    
        try {
    
    
          // 异步获取用户的角色
          const {
    
     roles } = await store.dispatch('user/getInfo')

          // 根据用户的角色,动态生成路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)

          // 调用 router.addRoutes 动态添加路由
          router.addRoutes(accessRoutes)

          // 使用 replace 访问路由,不会在 history 中留下记录
          next({
    
     ...to, replace: true })
        } catch (error) {
    
    
          // 移除 Token 数据
          await store.dispatch('user/resetToken')
          // 显示错误提示
          Message.error(error || 'Has Error')
          // 重定向到登录页面
          next(`/login?redirect=${
      
      to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    
    
    // 如果访问的 URL 在白名单中,则直接访问
    if (whiteList.indexOf(to.path) !== -1) {
    
    
      next()
    } else {
    
    
      // 如果访问的 URL 不在白名单中,则直接重定向到登录页面,并将访问的 URL 添加到 redirect 中
      next(`/login?redirect=${
      
      to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
    
    
  // 停止进度条
  NProgress.done()
})

Guess you like

Origin blog.csdn.net/weixin_42614080/article/details/107754668