在线文件地址
https://github1s.com/PanJiaChen/vue-element-admin/blob/HEAD/src/permission.js

说明

该文件是路由层面权限的控制代码,在main.js中加载,核心功能就是对页面中一些页面的访问做权限控制,比如未登录用户不可访问其他页面,已经登录用户还存在一个权限设置的问题,根据不同用户访问不同的路由配置表,以达到权限管理的母的。

文件目录
src/permission.js

引用文件

  1. main.js
  2. import './permission' // permission control

组件

进度条 nprogress

详见 文章 nprogress

分析

  1. import router from './router'
  2. import store from './store'
  3. import { Message } from 'element-ui'
  4. import NProgress from 'nprogress' // progress bar
  5. import 'nprogress/nprogress.css' // progress bar style
  6. import { getToken } from '@/utils/auth' // get token from cookie
  7. import getPageTitle from '@/utils/get-page-title'
  8. NProgress.configure({ showSpinner: false }) // NProgress Configuration
  9. const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist
  10. router.beforeEach(async(to, from, next) => {
  11. // start progress bar
  12. NProgress.start()
  13. // set page title
  14. document.title = getPageTitle(to.meta.title)
  15. // determine whether the user has logged in 判断用户是否登录
  16. const hasToken = getToken()
  17. if (hasToken) {
  18. if (to.path === '/login') {
  19. // if is logged in, redirect to the home page
  20. next({ path: '/' })
  21. NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
  22. } else {
  23. // determine whether the user has obtained his permission roles through getInfo
  24. const hasRoles = store.getters.roles && store.getters.roles.length > 0
  25. if (hasRoles) {
  26. next()
  27. } else {
  28. try {
  29. // get user info
  30. // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
  31. const { roles } = await store.dispatch('user/getInfo')
  32. // generate accessible routes map based on roles
  33. const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
  34. // dynamically add accessible routes
  35. router.addRoutes(accessRoutes)
  36. // hack method to ensure that addRoutes is complete
  37. // set the replace: true, so the navigation will not leave a history record
  38. next({ ...to, replace: true })
  39. } catch (error) {
  40. // remove token and go to login page to re-login
  41. await store.dispatch('user/resetToken')
  42. Message.error(error || 'Has Error')
  43. next(`/login?redirect=${to.path}`)
  44. NProgress.done()
  45. }
  46. }
  47. }
  48. } else {
  49. /* has no token*/
  50. // 未登录 分为白名单与其他路径
  51. if (whiteList.indexOf(to.path) !== -1) {
  52. // in the free login whitelist, go directly
  53. next()
  54. } else {
  55. // other pages that do not have permission to access are redirected to the login page. 其他无权访问的页面被重定向到登录页面
  56. next(`/login?redirect=${to.path}`)
  57. NProgress.done()
  58. }
  59. }
  60. })
  61. router.afterEach(() => {
  62. // finish progress bar
  63. NProgress.done()
  64. })

流程分析
判断用户是否登录

  • 已登录
    • 是否是login路径
      • 是:重定向到首页
      • 否:判断用户是否获得权限角色
        • 有:放行
        • 无:去获取用户权限角色然后再进行跳转
  • 未登录
    • 是否在白名单
      • 在:跳转
      • 不在:跳转到登录页面并携带该页面的参数

HACK

  1. // hack method to ensure that addRoutes is complete
  2. // set the replace: true, so the navigation will not leave a history record