1.菜单需要后端维护吗?
2.权限怎么设计比较好?支持路由和按钮
3.如何和后台关系起来
要做到路由和按钮级别的权限,刚好有过类似经验:
菜单需要后端维护吗?
不需要后端维护。
权限怎么设计比较好?支持路由和按钮
前端维护所有菜单,每个菜单需要有 privs 字段(权限相关)
// menu.js
[{
id: 'user',
name: '用户管理',
privs: ['USER_READ', 'USER_WRITE'],
},
{
id: 'role',
name: '角色管理',
privs: ['ROLE_READ', 'ROLE_WRITE'],
}]
登录系统时,获取用户信息,其中一个字段就存储用户拥有的权限信息,比如:
{ userId: 1, privs: ['USER_READ'] }
拿到用户的权限,与 menu.js 中每个菜单的权限(privs 字段)做交集,有交集说明用户可以看这个菜单,没有交集的菜单干掉,最终可以过滤出用户拥有权限的菜单数组。
上面👆给每个菜单两个权限
你也可以根据自己需要划分的更具体一点,一个权限控制一个按钮也行。
写个公共方法,看代码可能有点模糊,结合下面👇新增按钮的例子看应该能明白。
// currentPriv:菜单拥有的权限
// excludeCallback:用户的权限列表中没有该权限时做的事
// includeCallback:用户的权限列表中有该权限时做的事
function privButton (currentPriv, excludeCallback, includeCallback) {
// 获取用户拥有的权限
const privs = getItem('privs')
// 用户拥有的权限列表不包含菜单的菜单时执行 excludeCallback 回调
if (privs.indexOf(currentPriv) === -1) { // 不存在
return typeof excludeCallback === 'function' && excludeCallback()
} else {
// 用户拥有的权限列表包含菜单的菜单时执行 includeCallback 回调
return typeof includeCallback === 'function' && includeCallback()
}
}
以新增按钮举例:结合 privButton 代码逻辑,只有用户的权限列表中有 USER_WRITE 时才会渲染新增列表。
<div>
{
privButton('USER_WRITE', null, () => {
return (
<Button type="primary" onClick={() => this.handleCreateItem()}>
新增
</Button>
)
})
}
</div>
如何和后台关系起来
后端不存菜单,只存权限信息。
要做到路由和按钮级别的权限,刚好有过类似经验:
菜单需要后端维护吗?
不需要后端维护。
权限怎么设计比较好?支持路由和按钮
- 先说说怎么支持路由权限,即不同用户进入系统看到的菜单是不同的。
前端维护所有菜单,每个菜单需要有 privs 字段(权限相关)
// menu.js [{ id: 'user', name: '用户管理', privs: ['USER_READ', 'USER_WRITE'], }, { id: 'role', name: '角色管理', privs: ['ROLE_READ', 'ROLE_WRITE'], }]登录系统时,获取用户信息,其中一个字段就存储用户拥有的权限信息,比如:
{ userId: 1, privs: ['USER_READ'] }拿到用户的权限,与 menu.js 中每个菜单的权限(privs 字段)做交集,有交集说明用户可以看这个菜单,没有交集的菜单干掉,最终可以过滤出用户拥有权限的菜单数组。
- 再聊聊怎么做到按钮级别的权限。
上面👆给每个菜单两个权限
- USER_READ 读权限。可以看这个菜单,这个权限控制着查询按钮。(不会改变数据)
- USER_WRITE 写权限。修改数据相关的操作,这个权限控制着新增按钮、编辑按钮、删除按钮。
你也可以根据自己需要划分的更具体一点,一个权限控制一个按钮也行。
写个公共方法,看代码可能有点模糊,结合下面👇新增按钮的例子看应该能明白。
// currentPriv:菜单拥有的权限 // excludeCallback:用户的权限列表中没有该权限时做的事 // includeCallback:用户的权限列表中有该权限时做的事 function privButton (currentPriv, excludeCallback, includeCallback) { // 获取用户拥有的权限 const privs = getItem('privs') // 用户拥有的权限列表不包含菜单的菜单时执行 excludeCallback 回调 if (privs.indexOf(currentPriv) === -1) { // 不存在 return typeof excludeCallback === 'function' && excludeCallback() } else { // 用户拥有的权限列表包含菜单的菜单时执行 includeCallback 回调 return typeof includeCallback === 'function' && includeCallback() } }以新增按钮举例:结合 privButton 代码逻辑,只有用户的权限列表中有
USER_WRITE时才会渲染新增列表。<div> { privButton('USER_WRITE', null, () => { return ( <Button type="primary" onClick={() => this.handleCreateItem()}> 新增 </Button> ) }) } </div>如何和后台关系起来
后端不存菜单,只存权限信息。
嗯,大佬,目前也是这样设想的,后端只存权限,本身后端springsecurity也是通过权限key来控制接口权限的,看来想法正确了。谢谢大佬。
@dkvirus 请问config.ts的页面路由只能前端写死吗,还是可以从后端读取,由后台管理。
在ToB业务中对于权限的管理涉及的比较多,分享下对于权限与前端管理的想法:
以上是权限在不同应用场景使用情况,涉及到前端如何展示菜单,对业务操作的按钮。
我们先聊菜单——影响用户能看到什么样的菜单是由
// 一个高级财务报表页面
export default {
id: '@bi-report',
path: '/bi-report',
powerCode: [10010, 10086], // 功能权限
roleCode: ['REPORT_ADMIN'], // 角色权限
component: () => import('./bi-report')
}
接下来当应用启动优先拿到用户数据 存储在全局Store里面
{
"name":"王二狗"
…
"powerCode": ["10010", "10086"],
"roleCode": []
}
接下来需要有个LoadPlugins 的方法,传入当前用户的 powerCode,roleCode ,并且遍历需要挂载的 一个个页面入口,当两者能匹配上,当前被遍历的页面入口就会被挂载在路由配置文件上,和菜单配置文件上,反之则不挂载,不显示在菜单上。
下面聊聊业务权限按钮配置,
一个应用场景为例:一张单据流转到我这里需要处理,如果我是管理者我面临的是能不能审批和驳回,如果我是财务人员对于我处理的是支付和拒绝,如果我是提交者我对单据的操作可能是撤回和修改。
后端下发数据结构
{
"单据实体":"单据实体"
"ACTIONS": ["A1","A3","A4"]
}
前端定义好
{
'actionType': 'A1',
'label': '驳回',
'style': 'error',
'action': actionFn // 处理驳回函数
}
便利后端ACTIONS 然后由前端自己的配置文件来处理 渲染这些动作按钮。
简单探讨这些,欢迎交流
@muqiuren 你要是用 umi 的话,路由就应当在前端管理。只有服务端渲染时路由才在后端处理,umi 做的是单页应用,用的路由当然才在前端处理。
@muqiuren 你要是用 umi 的话,路由就应当在前端管理。只有服务端渲染时路由才在后端处理,umi 做的是单页应用,用的路由当然才在前端处理。
是的,之前切换到分离开发模式时,就在想有没有可能这么做,看了你的回答,觉得这么做完全没必要,后端只提供鉴权和数据就可以了,路由交给前端维护就行了。谢谢。
https://antd-plus.alitajs.com/components/authorized 权限组件 灵活性比较高
pro 本身不就有一个吗?
不一样的,你可以具体看下
1.菜单需要后端维护吗?
最好在后台维护,添加一个用户,需要给这个用户动态分配访问菜单,在后台维护会比较方便。
2.权限怎么设计比较好?支持路由和按钮
antdpro中把菜单与路由融合在一起,如果菜单能做权限,路由也可以做权限。
按钮需要特殊设定,但是在原型设计的时候,能把按钮功能设计成菜单,并且用户体验也设计的易用,这样就能简化权限控制。
弹出层中的编辑修改,只能用按钮权限来控制
3.如何和后台关系起来
后台比较麻烦
后台需要控制api访问接口的权限,例如 订单对象有4个api接口:查询、删除、修改、增加
如果后台api不做权限控制,如果知道一个url,很容易通过url地址,来获取所有功能,造成权限外延的泄露。
后台api权限与前端菜单权限又有一个对应关系,需要进行关联。
Most helpful comment
要做到路由和按钮级别的权限,刚好有过类似经验:
不需要后端维护。
前端维护所有菜单,每个菜单需要有 privs 字段(权限相关)
登录系统时,获取用户信息,其中一个字段就存储用户拥有的权限信息,比如:
拿到用户的权限,与 menu.js 中每个菜单的权限(privs 字段)做交集,有交集说明用户可以看这个菜单,没有交集的菜单干掉,最终可以过滤出用户拥有权限的菜单数组。
上面👆给每个菜单两个权限
你也可以根据自己需要划分的更具体一点,一个权限控制一个按钮也行。
写个公共方法,看代码可能有点模糊,结合下面👇新增按钮的例子看应该能明白。
以新增按钮举例:结合 privButton 代码逻辑,只有用户的权限列表中有
USER_WRITE时才会渲染新增列表。后端不存菜单,只存权限信息。