权限管理
项目中经常有的场景是不同的用户的权限不同。
- 不同的用户在页面中可以看到的元素和操作不同(控制元素显示和操作按钮)
- 不同的用户对页面的访问权限不同(控制路由菜单)
页面权限跟页面菜单 id 绑定。获取当前页面id后,找到对应的页面权限,控制页面按钮或者模块的显示隐藏。后端同步控制校验对应请求路由的权限。
菜单管理 (只是维护信息)
菜单绑定:页面元素和页面操作
页面元素:【元素标志】【元素名称】【操作->控制当前页面元素数据记录的增删改查】
页面操作:【操作标志】【操作名称】【API】
权限管理 (给角色授权菜单、操作、显示权限)
勾选菜单:给当前用户赋予可以展示的菜单
勾选操作:在有权限的菜单下勾选操作和显示权限
授予角色
权限基础信息维护好后,给用户授予角色(权限组)
Vue 可以基于全局指令来实现
Raect 可以基于 umi.js access 插件
// src/access.ts
export default function(initialState) {
const { userId, role, isAdmin, hasRoutes = [] } = initialState; // 后端维护和组织好权限数据
// 返回一个权限对象、每一个key对应一个布尔值(一个操作权限)
return {
canReadFoo: true,
canUpdateFoo: role === 'admin',
canDeleteFoo: foo => {
return foo.ownerId === userId;
},
adminRouteFilter: () => isAdmin, // 只有管理员可访问
normalRouteFilter: (route) => hasRoutes.includes(route.name), // initialState 中包含了的路由才有权限访问
};
}
路由和菜单的权限控制
routes: [ { path: '/foo', name: 'foo', // ... access: 'normalRouteFilter', // 会调用 src/access.ts 中返回的 normalRouteFilter 进行鉴权 }, { path: '/admin', name: 'admin', // ... access: 'adminRouteFilter', // 会调用 src/access.ts 中返回的 adminRouteFilter 进行鉴权 }, ]
页面内的权限控制
import React from 'react'; import { useAccess, Access } from 'umi'; const PageA = (props) => { const { foo } = props; const access = useAccess(); // access 实例的成员: canReadFoo, canUpdateFoo, canDeleteFoo if (access.canReadFoo) { // 任意操作 } return ( <div> <Access accessible={access.canReadFoo} fallback={<div>Can not read foo content.</div>}> Foo content. </Access> <Access accessible={access.canUpdateFoo()} fallback={<div>Can not update foo.</div>}> Update foo. </Access> <Access accessible={access.canDeleteFoo(foo)} fallback={<div>Can not delete foo.</div>}> Delete foo. </Access> </div> ); };