今天在公司写代码的时候遇到一个问题
正常来说我给路由配置权限 ,只需要去 routerPerssion.ts文件中配置好路径,与对应后端返回的角色标识匹配上就能实现权限的操作
问题
在配置后发现页面有问题 ,第一级路由 "消防管理" 的 element 属性定义了重定向到第二级路由 "消防日检" 的路径 PageUrl.FPM。这意味着当用户访问 "/消防管理" 时,他们将被重定向到 "/消防日检" 页面, 然后"/消防日检"他本身也是没有页面的,他会继续重定向到"/检查计划" ,如果此时用户没有"/检查计划"的权限,但是有日检和管理的权限的话 , 用户访问"/检查计划"会返回到上级菜单路径,上级菜单路径又重定向到了检查计划页面, 导致重复循环
解决方法 :
检查重定向部分
- 需要验证该路由是否包含了用户所具备的权限之一,如果不包含,则将该路由从菜单中隐藏,并设置
hasAuthority
属性为 false,表示该路由无权访问; - 如果该路由存在子路由
item.routes
,则递归遍历子路由进行相同的检查; - 最后,检查父级路由是否重定向到
hasAuthority
为 false 的子路由上,如果是,则将其重定向到第一个hasAuthority
不为 false 的子路由,如果没有,则重定向到 404 页面。
/**
* @desc 给路由模块注入权限
*/
const applyRouterPerssion = (permission: string[], roles: AccountRoleType[] = []) => {
return new Promise<void>((resolve, _) => {
function traverse(routes: PageRoute[], parent?: PageRoute) {
for (let index = 0; index < routes.length; index++) {
const item = routes[index];
const routePath = item.path as string;
if (routePath === '/') continue;
if (!item.element && (item.routes ?? []).length < 1) continue;
if (Object.prototype.hasOwnProperty.call(RouterPerssion, routePath) === false) continue;
// 系统默认角色账户[ADMIN],默认具备所有权限
if (roles.includes('ADMIN')) {
routes[index].hideInMenu = undefined;
routes[index].hasAuthority = undefined;
continue;
}
// 至少需要包含一个需要的权限
let needPerssion = (RouterPerssion as any)[routePath] as string[];
if (needPerssion.some((key) => permission.includes(key)) === false) {
routes[index].hideInMenu = true;
routes[index].hasAuthority = false;
}
if (item.routes && item.routes.length > 0) traverse(item.routes, item);
}
// 检查父级重定向
if (parent) {
let element = parent.element as React.ReactElement;
let child = routes.find((o) => o.path === element?.props.to);
if (child && child.hasAuthority === false) {
let _list = routes.filter((o) => o.hasAuthority !== false);
if (_list.length && _list[0].path) {
parent.element = <Navigate replace to={_list[0].path} />;
} else {
parent.element = <Navigate replace to="404" />;
}
}
}
}
traverse(basicRouter);
traverse(blankRouter);
resolve();
});
};