vue+elementui搭建后台管理界面(6登录和菜单权限控制)
不同的权限对应不同的路由(菜单),同时侧边栏也根据权限异步生成,实现登录和鉴权思路如下:
- 登录:点击登录,服务器验证通过后返回一个 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登录和菜单权限控制)的更多相关文章
- vue+elementui搭建后台管理界面(6登录和菜单权限控制[二])
根据权限计算路由的代码 /** * 通过meta.role判断是否与当前用户权限匹配 * @param roles * @param route */ function hasRoles (roles ...
- vue+elementui搭建后台管理界面(1登录)
1 node环境安装 从 node官网下载安装包 2 vue-cli npm install vue-cli -g 3 新建项目 vue init webpack vue-project 可保持默认, ...
- vue+elementui搭建后台管理界面(7 vuex和mockjs的使用)
将权限管理应用到系统,首先做好登录, 点击登录按钮后,触发以下动作 vuex 中的 login 动作,设置 cookie vuex 中的 getuserinfo , 获取权限.用户名.头像等 由于目前 ...
- vue+elementui搭建后台管理界面(2首页)
1 会话存储 使用html5的 sessionStorage 对象临时保存会话 // 保存会话 sessionStorage.setItem('user', username) // 删除会话 ses ...
- vue+elementui搭建后台管理界面
1 会话存储 使用html5的 sessionStorage 对象临时保存会话 // 保存会话 sessionStorage.setItem('user', username) // 删除会话 ses ...
- vue+elementui搭建后台管理界面(8 同步/异步获取数据渲染table)
elementui已经封装好了 el-table 组件,只需要指定 data 数据源即可,因此通常在 vue 实例生命周期的 created 阶段,从数据库获取数据,再将返回的数据绑定到 data 如 ...
- vue+elementui搭建后台管理界面(5递归生成侧栏路由)
有一个菜单树,顶层菜单下面有多个子菜单,子菜单下还有子菜单... 这时候就要用递归处理 1 定义多级菜单 修改 src/router/index.js 的 / 路由 { path: '/', redi ...
- vue+elementui搭建后台管理界面(3侧边栏菜单)
上一节搭好了主框架,但是标签页和侧边栏只是分别展示了各自的菜单,如何将二者联动起来? 定义路由规则:当有 children 属性时,从 children 里取出 path 填充到侧边栏,如: { pa ...
- vue+elementui搭建后台管理界面(4使用font-awesome)
使用font-awesome npm install --save font-awesome 修改 src/main.js 增加 import 'font-awesome/scss/font-awes ...
随机推荐
- JavaWeb 之 Filter 验证用户登录案例
需求: 1. 访问一个网站的资源.验证其是否登录 2. 如果登录了,则直接放行. 3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录". 代码实现: import j ...
- 使用 shell 脚本配置 iOS 工程
APP开发过程中,往往需要在多个网络环境或配置中进行切换,以获取不同配置的APP,甚至有时需要用一套代码经过简单的配置生成不同的APP.而手动配置费时费力,且容易出错.这里介绍用脚本工具,去生成不 ...
- MySQL Charset--UTF8和UTF8MB4对比测试
UTF8和UTF8MB4 在早期MySQL版本中,使用只支持最长三字节的UTF8字符集便可以存放所有Unicode字符.随着Unicode的完善,Unicode字符集收录的字符数量越来越多,最新版本的 ...
- 06-jQuery进阶
本篇主要介绍jQuery的正则.冒泡事件.委托事件.以及DOM操作.JavaScript对象以及ajax等知识: 一.正则 简而言之,正则的规则无论是各种语言均是通用的,故其规则中的字符便不再介绍了, ...
- FreeBSD设置开机同步时间
没有设置开机同步时间的话,重启之后时间不对. 如果装机时没正确设置时区,先设置时区:# tzsetup 用date命令手工设置时间一方面不方便,另一方面也依赖于本地管理员的时钟的正确性,那么网络上不同 ...
- MySQL/MariaDB数据库的查询缓存优化
MySQL/MariaDB数据库的查询缓存优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL架构 Connectors(MySQL对外提供的交互接口,API): ...
- python笔记35-装饰器
前言 python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象. 很多python初学者学到面向对象类和方法是一道大坎,那么p ...
- Centos7-重建官方yum源
删除yum源,重建官方 cd /etc/yum.repos.d/ #删除所有 rpm -Uvh --force http://mirror.centos.org/centos-7/7.7.1908/o ...
- 《exception》第九次团队作业:Beta冲刺与验收准备(大结局)
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 1.掌握软件黑盒测试技术:2.学会编制软件项目 ...
- Hadoop跨集群迁移数据(整理版)
1. 什么是DistCp DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具.它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成.它把文件和目录的列表作为map任务的 ...