element-admin路由权限配置详解(二)

一、项目权限分析

一个项目我们如何做好权限管理,取决于项目实际应用场景,比如说我们要做一个内容管理后台,可能只是简单的几个角色,我们就没有必要做的很复杂,只是需要一个权限模块,分为超级管理员,中级管理员,普通管理员,然后在新建用户的时候绑定到用户表上就行了,这样就可以满足日常需求了,这样的权限完全有我们上次讲到就完全够用了。

上一章我们讲解了基本的路由权限配置,从router.js到vuex,再到permission.js,整个流程做了一个梳理,如何配置,如何应用。在上一章中,我们大致将权限分为几个部分,比如:超级管理员,中级管理员,普通管理员等等,根据登录用户不同身份加载我们事先约定好的路由,当然在大型项目中可能会有很多的局限性,不够灵活,今天我们要讲的就是如何在单个路由做前端控制,通过用户信息返回roles列表,加载路由。

二、路由改造

如下所示,在需要加权限的路由上加上authority字段,默认路由不加authority所有权限下都可见。

// src/router/index.js

const routes = [
	{
    	path: '/article',
    	mete: { title: '内容管理'},
    	redirect: '/article/list',
    	children: [
  			{
				path: 'list',
				meta: { title: '文章列表'},
				authority: ['user'],
				component: () => import('@/views/article/list'),
			},
			{
				path: 'image',
				meta: { title: '图片管理'},
				authority: ['admin'],
				component: () => import('@/views/article/image'),
			}
 		]
    },{
		path: 'user',
		meta: { title: '用户管理'},
		authority: ['user', 'admin'],
		component: () => import('@/views/user/index'),
	}
]

三、路由权限方法使用

权限相关方法主要使用在store中的permission.js文件中,对导入的路由列表进行过滤,具体逻辑可以参考element-admin路由权限配置详解(一)

// utils/permission.js

/**
 * 跟进用户权限过滤路由列表
 * @param {Array} routes 路由列表
 * @returns
 */
export function getAuthRoutes(routes) {
  if (routes && routes.length) {
    return routes.filter((v) => {
      if (v.children) {
        v.children = getAuthRoutes(v.children)
        if (v.children.length === 1) {
          onlyOnechildrenRoute(v)
        }
        if (v.children == null || v.children.length == 0) return false
      } else if (!verifyAuthority(v)) {
        return false
      }
      return true
    })
  }
  return routes
}

/**
 * 根据权限过滤后子路由children只有一个时,
 * 判断父路由redirect地址是否在children存在
 * 不存在children的第一个path为父的redreact path
 */
function onlyOnechildrenRoute(route) {
  route.redirect = route.children[0].path
}

/**
 * 验证路由上的权限是否存在
 * 根据用户返回权限列表判断当前路由是否通过
 * @param {Object} route 路由对象
 * @returns
 */
function verifyAuthority(route) {
  if (!route.authority) return true
  // getAuthority 返回的是登录用户信息返回的roles,可以保存在store中或者localStorage中
  const roles = getAuthority()
  return route.authority.some((citem) => roles.includes(citem))
}

四、permission.js 修改

import router from './router'
import store from './store'
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'

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist
// eslint-disable-next-line
router.beforeEach(async (to, from, next) => {
  NProgress.start()
  document.title = getPageTitle(to.meta.title)
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      const hasGetUserInfo = store.getters.name
      if (!hasGetUserInfo) {
        try {
          // get user info
          await store.dispatch('user/getInfo')
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          next()
          NProgress.done()
        }
      }
      // 获取路由
      if (!store.getters.routes.length) {
        const routes = await store.dispatch('permission/GenerateRoutes')
        router.addRoutes(routes)
        next({ path: to.path, query: to.query, replace: true })
        NProgress.done()
      } else {
        next()
        NProgress.done()
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

本文主要讲解另一种权限方法的实现,主要在第三步的方法,如有疑问可以留言互相探讨,下次我们讲解如何通过自定义指令实现按钮级的权限

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码猿小菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值