vue+elementui搭建后台管理界面(6登录和菜单权限控制)

摘要:
response.data){reject}constdata=response.dataconstroles=data.dataif{commit}else{rejectt()}if{提交}if{提交}response.data.roles=rolesresolve})。Catch})},3菜单权限前端保存一个路由表,记录每条路由和所需的权限。然后根据用户信息中的角色计算相应的权限,生成具有权限的菜单,并装载路由。然而,这只是页面控制,后端还需要相应地进行权限验证。

不同的权限对应不同的路由(菜单),同时侧边栏也根据权限异步生成,实现登录和鉴权思路如下:

  • 登录:点击登录,服务器验证通过后返回一个 token ,然后存到 cookie,再根据 token 拉取用户权限
  • 鉴权:通过 token 获取对应的roles, 计算有权限的路由,使用 router.addRoutes 动态加载路由

数据和操作通过 vuex 进行控制

1 登录

登录按钮 click 事件触发登录动作:

/** ...省略的代码 */
this.$store.dispatch('LoginByUsername', {
    'username': username, 'password': password
})
.then(() => {
    this.logining = false
    this.$notify.success({
    message: '欢迎登录',
    duration: 3 * 1000,
    })
    // 重定向到首页
    this.$router.push({ path: this.redirect || '/' })
})
.catch(err => {
    this.logining = false
    this.$alert(err, {
        type: 'warning',
        confirmButtonText: 'ok'
    })
})
/** ...省略的代码 */

action:

// 登入
LoginByUsername({commit }, userInfo){
    const username = userInfo.username.trim()
    return new Promise((resolve, reject) => {
        loginByUsernameApi(username, userInfo.password)
        .then(response=> {
            const data = response.data
            setToken(data.token) // 储存token
            commit('SET_TOKEN', data.token)
            commit('SET_ACCOUNT', username)
            resolve()
        })
        .catch(err => {
            reject(err)
        })
    })
}
/** ...省略的代码 */

登录成功,服务端返回一个token,然后储存到本地 cookie。

2 获取用户权限

对每个路由,在全局钩子 router.beforeEach 中拦截,判断是否已获取token,之后再获取用户的基本信息

/** ...省略的代码 */
if(store.getters.token) {
    // 判断当前用户是否已拉取完user_info信息
    if(store.getters.roles.length === 0){
        // 拉取用户信息
        store.dispatch('GetUserInfo').then(resp => {
            const roles = resp.data.roles
            next()
            /** ...省略的代码 */
            })
        })
    }
}
/** ...省略的代码 */

action:

// 获取用户信息, 名称、头像、权限
GetUserInfo({commit, state}) {
    return new Promise((resolve, reject) => {
        getLoginUserInfoApi(state.token)
        .then(response => {
            if(!response.data){
                reject('error')
            }
            const data = response.data
            const roles = data.data
            if(roles && roles.length > 0){
                commit('SET_ROLES', roles)
            }else {
                reject()
            }

            if(data.name){
                commit('SET_NAME', data.name)
            }

            if(data.avatar){
                commit('SET_AVATAR', data.avatar)
            }

            response.data.roles = roles
            resolve(response)
        })
        .catch(err => {
            reject(err)
        })
    })
},

3 菜单权限

前端保存一份路由表,记录每一个路由和需要的权限。
再根据用户信息里的 roles 计算对应的权限,然后生成有权限的菜单,再挂载路由。
但这只是页面控制,后端也要相应的做权限验证。

  • 创建vue实例时使用vue-router挂载登录和一些公用页面,如首页、图表等
  • 用户登录后,将获取的roles和路由表的权限比较,生成用户可访问的路由表
  • 调用router.addRoutes添加可访问的路由
  • 使用vuex管理路由表,生成侧边栏菜单

首先是 router.js 路由表

import Vue from 'vue'
import Router from 'vue-router'
import Container from '@/containers/Container'
import Login from '@/views/login'
import Page404 from '@/views/404'
import Dashboard from '@/views/dashboard'

/** router modules */
import systemRouter from './modules/system'

Vue.use(Router)

export const constantRouterMap = [
  {
    path: '/login',
    hidden: true,
    component: Login
  },
  {
    path: '/404',
    hidden: true,
    component: Page404
  },
  {
    path: '/',
    redirect: '/dashboard',
    component: Container,
    name: '首页',
    hidden: false,
    meta: { title: '首页', icon: '', noCache: true },
    children: [
      {
        path: 'dashboard',
        name: 'Dashboard',
        component: Dashboard,
        meta: { title: '首页', icon: 'fa fa-dashboard fa-lg', noCache: true }
      },
      {
        path: 'table',
        name: '表格综合实例',
        component: Form,
        meta: { title: '表格综合实例', icon: '', noCache: true }
      },
      // { path: '*', redirect: '/404', hidden: true }
    ]
  },
]

export default new Router({
  mode: 'hash',
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRouterMap
})

export const asyncRouterMap = [
  /** 其他的异步路由表 */
  systemRouter,
  { path: '*', redirect: '/404', hidden: true }
]

同级目录下的 ./modules/system.js 路由表

import Container from '@/containers/Container'
/**
 * 系统管理相关路由
 */
const systemRouter = {
  path: '/system',
  component: Container,
  redirect: '/system/permit/account',
  name: '系统管理',
  meta: {
    title: '系统管理',
    roles: ['/system']
  },
  children: [
    {
      path: 'permit',
      name: '权限管理',
      hidden: false, 
      redirect: '/system/permit/account',
      component: () => import('@/views/system/permit'),
      meta: { 
        title: '权限管理', 
        icon: 'fa fa-cog fa-lg',
        roles: ['/system/permit']  
      },
      children: [
        { path: 'account', name: '用户', 
          component: () => import('@/views/system/permit/account'), 
          meta: { title: '用户', icon: 'form', roles: ['/system/permit/account'] } 
        },
        { path: 'accountgroup', name: '用户组',  
          component: () => import('@/views/system/permit/accountgroup'), 
          meta: { title: '用户组', icon: 'form', roles: ['/system/permit/accountgroup'] } 
        },
        { path: 'role', name: '角色', 
          component: () => import('@/views/system/permit/role'),
           meta: { title: '角色', icon: 'form', roles: ['/system/permit/role'] } 
        },
        { path: 'authorize', name: '授权', 
          component: () => import('@/views/system/permit/authorize'),
           meta: { title: '授权', icon: 'form', roles: ['/system/permit/authorize'] } 
        },
      ]
    },
        
  ],
}

export default systemRouter

roles: ['/system/permit/account'] 表示该页面需要的权限是 '/system/permit/account' 后端返回的 roles 里有这个记录则能访问对应的页面
而 '/system/permit/account' 是 '/system/permit' 的子路由,所以要访问 '/system/permit/account',后端返回:

roles: ['/system', '/system/permit', '/system/permit/account']

注意: 404页面要最后加载,如果放在 constantRouterMap 中,所有后面的页面都会被拦截到404

免责声明:文章转载自《vue+elementui搭建后台管理界面(6登录和菜单权限控制)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇刘强东,揭开京东未来盈利迷局C#远程调用技术WebService修炼手册下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python读写excel练习_去除excel中乱码行,并添加列

需求: 把app_student.xls里面的数据, 1、如果这一行数据里面有乱码(及包含?),那么就删掉 2、再加上一列,是否毕业 3、如果班级是天蝎座的话,毕业这一列写成毕业 4、其他班级的写成未毕业 原始数据: 实现: import xlrd,xlwt EXCEL_NAME = 'app_student.xls' def delete_messy_...

旋转机械故障诊断公开数据集整理

转自:https://blog.csdn.net/hustcxl/article/details/89394428 旋转机械故障诊断公开数据集整理众所周知,当下做机械故障诊断研究最基础的就是数据,再先进的方法也离不开数据的检验。笔者通过文献资料收集到如下几个比较常用的数据集并进行整理。鉴于目前尚未见比较全面的数据集整理介绍。数据来自原始研究方,笔者只整理数...

微信小程序商城订单上拉加载更点击切换订单状态(接口)

实现功能:如图 html (tab组件 需要的话请查看博客) <Tab tabList="{{tabList}}"bindtabsItemChange="tabsItemChange"> <view class="order"wx:for="{{orderList}}"wx:for-index="index"wx:key="i...

用 Java 爬美女图片,厉害了。。

目的 爬取搜狗图片上千张美女图片并下载到本地 准备工作 爬取地址:https://pic.sogou.com/pics?query=美女 分析 打开上面的地址,按F12开发者工具 - NetWork - XHR - 页面往下滑动XHR栏出现请求信息如下: Request URL : https://pic.sogou.com/napi/pc/searchL...

vue 中使用 axios 封装及使用

一, 配置BaseUrl /** * { * dev: '开发环境配置信息', * test: '测试环境配置信息', * prod: '线上环境配置信息' * } */ function conf (base = {}) { if (process.env.NODE_ENV === 'production' || proces...

QT项目性能调优小记

最近的项目用到了QT 5.5,项目在运行过程中出现了一段时间CPU占用率持续25%,并频繁断网的情况,遂决定对项目性能进行优化。 优化工具也是VS2010自带的性能分析工具,具体的使用方法参见:http://www.cnblogs.com/smark/archive/2011/10/12/2208039.html 其中可以选择“just my code”过...