0


vue-element-adminn实现权限管理(后端只控制权限roles)

用户应该分为三类:

​ 1、普通用户(user):只允许登录前台小程序端并进行基本的操作、不能进行后台管理系统的任何操作。

​ 2、店铺管理员(admin):允许管理店铺的栏目CRUD操作、商品CRUD操作、评论的查看与删除、查看店铺的销售情况等。

​ 3、超级管理员(super):允许进行店铺管理和用户管理等操作、能查看系统的用户数和店铺数等基本统计。


具体实现

  1. 创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
  2. 当用户登录后,获取用户roles,将roles和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
  3. 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
  4. 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

代码层面:

1. 普通用户登录拒绝访问后端:

代码文件结构
vue前端:

//用户登录获取tokenlogin({ commit }, userInfo){const{ phone, userPassword }= userInfo
    returnnewPromise((resolve, reject)=>{login({phone: phone.trim(),userPassword: userPassword.trim(),method:1}).then(response=>{//method 为一时代表是登录后台管理系统const{ data }= response
        commit('SET_TOKEN', data.token)setToken(data.token)resolve()}).catch(error=>{reject(error)})})},

controller:

@PostMapping("/login")publicResultlogin(@RequestBodyUser user){if(user.getMethod()==1){//为后台发出的登录请求,需要检验权限String roles = userService.findUserByPhone(user.getPhone()).getRoles();if(roles.equals("user")){//普通用户,阻止登录后台returnResult.error().message("您没有足够的权限");}}......省略了其它登录处理代码
2. admin(店铺管理员) 与 super(超级管理员) 不同身份登录能提供不同路由
1.后端返回的用户对象(必须携带roles字段):

在这里插入图片描述

2. vue-element-admin处理:

vue-element-admin登录并改变路由的开始:
在这里插入图片描述

import router from'./router'import store from'./store'import{ Message }from'element-ui'import NProgress from'nprogress'// progress barimport'nprogress/nprogress.css'// progress bar styleimport{ getToken }from'@/utils/auth'// get token from cookieimport getPageTitle from'@/utils/get-page-title'

NProgress.configure({showSpinner:false})// NProgress Configuration//白名单const whiteList =['/login']// no redirect whitelist

router.beforeEach(async(to, from, next)=>{// start progress bar
  NProgress.start()// set page title
  document.title =getPageTitle(to.meta.title)//获取token// determine whether the user has logged inconst hasToken =getToken()if(hasToken){//是否为登录if(to.path ==='/login'){//去首页next({path:'/'})
      NProgress.done()}else{//从vuex中获取权限const hasRoles = store.getters.roles && store.getters.roles.length >0if(hasRoles){//如果存在则放行next()}else{try{//roles 必须是一个数组//获取用户信息和权限信息,存到vuex中const{ roles }=await store.dispatch('user/getInfo')//生产路由数据const accessRoutes =await store.dispatch('permission/generateRoutes', store.getters.roles)//const accessRoutes = []// dynamically add accessible routes
          router.addRoutes(accessRoutes)var tempRoutes = router.options.routes.slice(0,3).concat(accessRoutes);//将原路由侧边栏显示截取为初始三个(作者其实不支持这样)
          router.options.routes = tempRoutes;//将路由添加到侧边栏(作者其实不支持这样)// hack method to ensure that addRoutes is complete// set the replace: true, so the navigation will not leave a history recordnext({...to,replace:true})}catch(error){// remove token and go to login page to re-loginawait store.dispatch('user/resetToken')
          Message.error(error ||'Has Error')//next(`/login?redirect=${to.path}`)next({path:'/'})
          NProgress.done()}}}}else{/* has no token*/if(whiteList.indexOf(to.path)!==-1){// in the free login whitelist, go directlynext()}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(()=>{// finish progress bar
  NProgress.done()})

关键的处理函数(getInfo、generateRoutes)在store/文件目录下:
在这里插入图片描述
store/modules/permission.js:

const actions ={generateRoutes({ commit }, roles){returnnewPromise(resolve=>{//存的是有权限的路由,是一个数组let accessedRoutes
      if(roles.includes('admin')){
        accessedRoutes =filterAsyncRoutes(asyncRoutes, roles)}else{
        accessedRoutes =filterAsyncRoutes(asyncRoutes, roles)}//commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}}......部分代码

store/modules/user.js:

//获取用户信息getInfo({ commit, state }){returnnewPromise((resolve, reject)=>{//调用api/user里面的接口getInfo(state.token).then(response=>{const{ data }= response

        if(!data){returnreject('Verification failed, please Login again.')}const user = data.user
        //console.log(user);commit('SET_NAME', user.username)commit('SET_AVATAR', user.headImg)var temp_roles =[user.roles];//vue-element-admin里面roles必须为数组//console.log(temp_roles);commit('SET_ROLES', temp_roles)//设置权限resolve(data)}).catch(error=>{reject(error)})})},......部分代码

router/index.js

import Vue from'vue'import Router from'vue-router'

Vue.use(Router)/* Layout */import Layout from'@/layout'/**
 * Note: sub-menu only appear when route children.length >= 1
 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
 *
 * hidden: true                   if set true, item will not show in the sidebar(default is false)
 * alwaysShow: true               if set true, will always show the root menu
 *                                if not set alwaysShow, when item has more than one children route,
 *                                it will becomes nested mode, otherwise not show the root menu
 * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
 * name:'router-name'             the name is used by <keep-alive> (must set!!!)
 * meta : {
    roles: ['admin','editor']    control the page roles (you can set multiple roles)
    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
  }
 *//**
 * constantRoutes
 * a base page that does not have permission requirements
 * all roles can be accessed
 * 不需要权限就可以访问的路由
 */exportconst constantRoutes =[{path:'/login',component:()=>import('@/views/login/index'),// “@”指的是src目录hidden:true},{path:'/404',component:()=>import('@/views/404'),hidden:true},{//侧边栏主页路由path:'/',component: Layout,redirect:'/dashboard',children:[{path:'dashboard',name:'Dashboard',component:()=>import('@/views/dashboard/index'),meta:{title:'主页',icon:'dashboard'}}],}]//异步挂载的路由//动态需要根据权限加载的路由表exportconst asyncRoutes =[{//侧边栏用户管理页路由path:'/user',component: Layout,redirect:'/user',children:[{path:'user',name:'User',component:()=>import('@/views/user/user'),meta:{title:'用户管理',icon:'user',roles:['super']}}]},{//侧边栏店铺管理页路由path:'/store',component: Layout,redirect:'/store',children:[{path:'store',name:'Store',component:()=>import('@/views/store/store'),meta:{title:'店铺管理',icon:'shopping',roles:['super']}}]},{//侧边栏发布管理页路由path:'/commondity',component: Layout,redirect:'/commondity/column',name:'Commodity',meta:{title:'发布管理',icon:'edit',roles:['admin']},children:[{path:'column',name:'Column',component:()=>import('@/views/column/column'),meta:{title:'栏目管理',icon:'list',roles:['admin']}},{path:'product',name:'Product',component:()=>import('@/views/product/product'),meta:{title:'商品管理',icon:'money',roles:['admin']}},]},{//侧边栏订单管理页路由path:'/order',component: Layout,redirect:'/order/order',name:'Order',meta:{title:'订单管理',icon:'clipboard',roles:['admin']},children:[{path:'history_order',name:'history_Order',component:()=>import('@/views/order/order'),meta:{title:'历史订单管理',icon:'skill',roles:['admin']}},{path:'receive_order',name:'Receive_order',component:()=>import('@/views/receive_order/receive_order'),meta:{title:'接单管理',icon:'people',roles:['admin']}},]},{//侧边栏评论管理页路由path:'/comment',component: Layout,redirect:'/comment',children:[{path:'comment',name:'Comment',component:()=>import('@/views/comment/comment'),meta:{title:'评论管理',icon:'message',roles:['admin']}}]},{path:'external-link',component: Layout,children:[{path:'https://gitee.com/x_y_king/master-goose',meta:{title:'项目地址',icon:'link'}}]},{path:'*',redirect:'/404',hidden:true}];constcreateRouter=()=>newRouter({// mode: 'history', // require service supportscrollBehavior:()=>({y:0}),routes: constantRoutes
})const router =createRouter()// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465exportfunctionresetRouter(){const newRouter =createRouter()
  router.matcher = newRouter.matcher // reset router}exportdefault router
3. 可以参考B站视频:

B站—vue-element-admin权限验证流程讲解

vue后台管理不同权限路由实现方式:

通过获取当前用户的权限去比对路由表,生成当前用户具有的权限可访问的路由表,通过

router.addRoutes

动态挂载到

router

上。

权限控制的主体思路,前端会有一份路由表,它表示了每一个路由可访问的权限。当用户登录之后,通过 token 获取用户的 role ,动态根据用户的 role 算出其对应有权限的路由,再通过

router.addRoutes

动态挂载路由。但这些控制都只是页面级的,说白了前端再怎么做权限控制都不是绝对安全的,后端的权限验证是逃不掉的。现在就是前端来控制页面级的权限,不同权限的用户显示不同的侧边栏和限制其所能进入的页面(也做了少许按钮级别的权限控制),后端则会验证每一个涉及请求的操作,验证其是否有该操作的权限,每一个后台的请求不管是 get 还是 post 都会让前端在请求

header

里面携带用户的 token,后端会根据该 token 来验证用户是否有权限执行该操作。若没有权限则抛出一个对应的状态码,前端检测到该状态码,做出相对应的操作。


本文转载自: https://blog.csdn.net/skyxya/article/details/129287209
版权归原作者 Xxxy _ 所有, 如有侵权,请联系我们删除。

“vue-element-adminn实现权限管理(后端只控制权限roles)”的评论:

还没有评论