首页 >> 大全

3.RBAC权限设计思想

2023-09-05 大全 28 作者:考证青年

RBAC权限详解 权限设置 1.权限点

权限:在一个系统内是否具有做某个操作的权利

权限分为两个级别

            1. 菜单权限:是否有权限访问某个菜单2. 按钮权限:是否有权限操作 页面上的某个按钮功能

2.业务逻辑

对于权限数据来说,有两个级别的设置

1.能不能访问谋个页面

2.在页面上,能不能操作某个按钮

3.RBAC权限设计思想

目标:不同账号登录系统后看到不同的页面, 能执行不同的功能

模式如下

三个关键点:

用户: 就是使用系统的人

权限点:这个系统中有多少个功能(例始:有3个页面,每个页面上的有不同的操作)

角色:不同的权限点的集合

实际上就是

给用户分配角色给角色分配权限点

实际业务中:

.先给员工分配一个具体的角色然后给角色分配具体的权限点 (工资页面 工资页面下的操作按钮)员工就拥有了权限点 4.权限具体业务

具体步骤 1.动态生成左侧菜单-方法

在中直接静态写死的动态路由表改造成通过 方法调用添加的形式

// 引入所有的动态路由表(未经过筛选)
import router, { asyncRoutes } from '@/router'
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {NProgress.start() // 启动进度条if (store.getters.token) {if (to.path === '/login') {next('/')} else {if (!store.getters.userId) {// 判断userInfo有没有id值,如果没有就进user/getUserInfoconst menus = await store.dispatch('user/getUserInfo')console.log('当前用户可以访问的权限是', menus)// 根据用户的实际权限menus,可以在asyncRoutes筛选出用户可以访问的权限const filterRoute = asyncRoutes.filter(route => {return menus.includes(route.children[0].name)})// 因为404页面在路由的中间位置,要进去之前404路由后面的路由时,直接进404页面了// 把404路由添加到所有路由的末尾就可以解决这个问题filterRoute.push( // 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true })// 改写成动态添加路由// addRoutes用来动态添加路由配置// 只有在这里设置了补充路由配置,才能去访问页面,如果没有设置的话,左边的菜单不显示的router.addRoutes(filterRoute)// 把他们保存到vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoute)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})} else {next()}}} else {if (whiteList.includes(to.path)) {next()} else {next('/login')}}
})

我们发现左侧的菜单只剩下静态的首页了,浏览器手动输入某一个动态路由地址,依旧是可用的,这证明我们其实已经把动态路由添加到我们的路由系统了。

2.动态生成左侧菜单-改写菜单保存位置

当前的菜单渲染使用的数据:this. r o u t e r . o p t i o n s . r o u t e s 这 个 数 据 是 固 定 , a d d R o u t e s 添 加 的 路 由 表 只 存 在 内 存 中 , 并 不 会 改 变 t h i s . .. 这个数据是固定,添加的路由表只存在内存中,并不会改变this. ..这个数据是固定,添加的路由表只存在内存中,并不会改变this...

目标:调用.() , 想要数据反映到视图上, 将路由信息存在vuex中

2.1定义vuex管理菜单数据

在src/store/下补充menu.js :

// 导入静态路由
import { constantRoutes } from '@/router'
export default {namespaced: true,state: {// 先以静态路由作为菜单数据的初始值menuList: [...constantRoutes]},mutations: {setMenuList(state, asyncRoutes) {// 将动态路由和静态路由组合起来state.menuList = [...constantRoutes, ...asyncRoutes]}}
}

src/store/index.js中注册这个模块

2.2提交生成完整的菜单数据

修改src/.js:

if (!store.getters.userId) {await store.dispatch('user/getUserInfo')// 把动态路由数据交给菜单store.commit('menu/setMenuList', asyncRoutes)// 把动态路由添加到应用的路由系统里router.addRoutes(asyncRoutes)
}

2.3菜单生成部分改写使用vuex中的数据

routes() {// 拿到的是一个完整的包含了静态路由和动态路由的数据结构// return this.$router.options.routesreturn this.$store.state.routeMenu.menuList
}

3.使用权限数据做过滤处理 通过后台返回的权限数据, 过滤出要显示的菜单, 过滤使用路由的name作为标识从中获取返回值

本质上是一个 它的 结果可以通过const res = await 名来接收

store//user.js

_权限设计模型_权限设计思路

// 用来获取用户信息的actionasync getUserInfo(context) {// 1. ajax获取基本信息,包含用户idconst rs = await getUserInfoApi()console.log('用来获取用户信息的,', rs)// 2. 根据用户id(rs.data.userId)再发请求,获取详情(包含头像)const info = await getUserDetailById(rs.data.userId)console.log('获取详情', info.data)// 把上边获取的两份合并在一起,保存到vuex中context.commit('setUserInfo', { ...info.data, ...rs.data })return rs.data.roles.menus},

4.在.js中过滤

if (!store.getters.userId) {// 有token,要去的不是login,就直接放行// 进一步获取用户信息// 发ajax---派发action来做const menus = await store.dispatch('user/getUserInfo')console.log('当前用户能访问的页面', menus)console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面const filterRoutes = asyncRoutes.filter(route => {const routeName = route.children[0].namereturn menus.includes(routeName)})// 一定要在进入主页之前去获取用户信息// addRoutes用来动态添加路由配置// 只有在这里设置了补充了路由配置,才可能去访问页面// 它们不会出现左侧router.addRoutes(filterRoutes)// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoutes)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})}

注意事项

代码示例

    if (!store.getters.userId) {// 有token,要去的不是login,就直接放行// 进一步获取用户信息// 发ajax---派发action来做const menus = await store.dispatch('user/getUserInfo')console.log('当前用户能访问的页面', menus)console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面const filterRoutes = asyncRoutes.filter(route => {const routeName = route.children[0].namereturn menus.includes(routeName)})// 一定要在进入主页之前去获取用户信息// 把404加到最后一条filterRoutes.push( // 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true })// addRoutes用来动态添加路由配置// 只有在这里设置了补充了路由配置,才可能去访问页面// 它们不会出现左侧router.addRoutes(filterRoutes)// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoutes)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})} 

/index.js中

// 重置路由
export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
}

这个方法就是将路由重新实例化,相当于换了一个新的路由,之前**加的路由就不存在了,需要在登出的时候, 调用一下即可**

import { resetRouter } from '@/router'
// 退出的action操作
logout(context) {// 1. 移除vuex个人信息context.commit('removeUserInfo')// 2. 移除token信息context.commit('removeToken')// 3. 重置路由resetRouter()// 4. 重置 vuex 中的路由信息 只保留每个用户都一样的静态路由数据//    在moudules中的一个module中去调用另一个modules中的mutation要加{root:true}context.commit('setMenuList', [], { root: true })
}

4.控制操作按钮

定义全局检测的方法:

Vue.prototype.$checkPoint = function(pointKey) {if (store.state.user.userInfo.roles.points) {// 进行权限点判断return store.state.user.userInfo.roles.points.includes(pointKey)}// 没有权限点POINTS信息, 说明用户没有身份, 没有任何权限return false

在模板中通过if来控制按钮显示

<template><div class="dashboard-container"><div class="app-container"><el-card><el-button v-if="$checkPoint('CKGZ')">查看工资el-button>el-card>div>div>
template>

$中的参数以系统中权限点的标识符为准。

或者自定义指令控制按钮显示

在main.js中定义全局指令

// 注册一个全局自定义指令 `v-allow`
Vue.directive('allow', {// 当被绑定的元素插入到 DOM 中时……inserted: function(el, binding) {// v-focus="'abc'"  ===> binding.value = 'abc'if (store.state.user.userInfo.roles.points.includes(binding.value)) {// 元素是可见的} else {el.style.display = 'none'}}

使用

<el-buttonv-allow="'import_employee'"type="warning"size="small"@click="$router.push('/import')">导入excel</el-button>

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了