Open
Description
登录
权限列表从登录接口返回,根据当前的 mock 数据将会取得 canReadFoo
应和前端 token 等信息保存到 localStorage 或 cookie 中,可以使用明文存储,前端的权限验证可以被用户绕过。因此,前端的权限验证通常作为后端权限验证的补充。
菜单
这个脚手架用的路由菜单还是 pro-layout 因此需要延用该组件的 api 定义。
export interface MenuDataItem {
/** @name 子菜单 */
children?: MenuDataItem[];
/** @name 在菜单中隐藏子节点 */
hideChildrenInMenu?: boolean;
/** @name 在菜单中隐藏自己和子节点 */
hideInMenu?: boolean;
/** @name 在面包屑中隐藏 */
hideInBreadcrumb?: boolean;
/** @name 菜单的icon */
icon?: React.ReactNode;
/** @name 自定义菜单的国际化 key */
locale?: string | false;
/** @name 菜单的名字 */
name?: string;
/** @name 用于标定选中的值,默认是 path */
key?: string;
/** @name disable 菜单选项 */
disabled?: boolean;
/** @name 路径,可以设定为网页链接 */
path?: string;
/**
* @deprecated 当此节点被选中的时候也会选中 parentKeys 的节点
* @name 自定义父节点
*/
parentKeys?: string[];
/** @name 隐藏自己,并且将子节点提升到与自己平级 */
flatMenu?: boolean;
/** @name 指定外链打开形式,同a标签 */
target?: string;
[key: string]: any;
}
此处只需处理,菜单的显隐即可。比如用户没有访问页面 /admin
的权限,但是用户知道该路由路径,直接通过浏览器访问的行为与菜单的权限管理无关。将在路由权限中处理。
组件级别
提供权限相关的 api 供用户使用
handleAccess
通过函数重新定义权限,可以在 layout 中对当前的权限做一个数据加工
import React, { useEffect } from 'react';
import { handleAccess } from '@umijs/tnf/access';
const Layout = (props) => {
useEffect(() => {
handleAccess((access) => {
let accessObj = {} as any;
// { currentAuthority: 'admin' }
switch (access.currentAuthority) {
case 'admin':
accessObj.canReadFoo = true;
accessObj.canUpdateFoo = true;
accessObj.canDeleteFoo = true;
break;
default:
break;
}
return {...access,...accessObj}
})
}, [])
return <>TODO</>;
};
export default Layout;
useAccess
通过 Hooks 获取用户的权限,返回的值为处理加(handleAccess)后的值
import React from 'react';
import { useAccess } from '@umijs/tnf/access';
const PageA = (props) => {
const { foo } = props;
const access = useAccess();
if (access.canReadFoo) {
// 如果可以读取 Foo,则...
}
return <>TODO</>;
};
export default PageA;
Access
提供组件 <Access />
对应用进行权限控制
import React from 'react';
import { Access } from '@umijs/tnf/access';
const PageA = (props) => {
return (
<div>
<Access
accessible={access.canReadFoo}
fallback={<div>Can not read foo content.</div>}
>
Foo content.
</Access>
</div>
);
};
umi中也提供 https://umijs.org/docs/max/access#access-1
路由权限
vue 和 ng 中都提供了路由守卫的概念,特别是 ng 中的路由守卫,是一个很完整的设计 https://angular.dev/api/router/CanActivate 感觉可以参考的做一个。此处可以解上面提到的用户知道路由地址直接跳过菜单权限的问题。
现在的类似做法是使用 Access 组件包裹页面组件,但更好的做法应该是提供类似 loader 的方法,如果用户没有定义则默认取菜单数据验证
import { createFileRoute } from '@umijs/tnf/router';
export const Route = createFileRoute('/account/center/applications')({
component: Applications,
loader: () => queryAccountCenterFakeList({ count: 30 }),
access: (access)=>{
// 返回 false,提示没有权限访问,展示 403 页面,或者跳转都可以?
return false;
}
});
Metadata
Metadata
Assignees
Labels
No labels