Umi4 搭建的后台管理系统考虑的几种权限管理方案

904 阅读2分钟

引言

本文章为基于Umi4的后台管理系统考虑的权限管理方案

在开发后台管理系统的过程中,我们不可避免的会涉及到权限管理。比如超管可以访问到所有的界面,某些用户只能访问到指定的页面

方法一 前端本地配置权限

步骤

  1. 打开权限管理插件

    Umi4 中自带了权限管理的插件,我们只需要在.umirc.ts文件中打开access项配置即可

    import { defineConfig } from '@umijs/max';
    
    export default defineConfig({
      access: {}, // 必须配置此项
      // ...
    })
    
  2. 配置自定义的权限

    src目录下新建access.ts文件,配置自定义的权限

    export default (initialState: any) => {
      // 在这里按照初始化数据定义项目中的权限,统一管理
      // 参考文档 https://umijs.org/docs/max/access
      const { routes = {} } = initialState; // 从后端请求的routes
    
      const canSeeSuperAdmin =
        initialState && initialState?.currentUser?.isSuperAdmin;
      return {
        canSeeSuperAdmin,
        normalRouteFilter: (route: any) => Object.keys(routes).includes(route.name),
      };
    };
    
  3. 为对应页面增加权限校验

    我们需要在.umirc.ts文件中的路由选项中加入access配置项

    import { defineConfig } from '@umijs/max';
    
    export default defineConfig({
      access: {},
      routes: [
        {
          name: '首页',
          path: '/home',
          component: '@/pages/Home',
          icon: 'HomeOutlined',
          access: 'normalRouteFilter',
        },
        {
          name: '用户管理',
          path: '/userManage',
          component: '@/pages/UserManage',
          icon: 'UserOutlined',
          access: 'canSeeSuperAdmin',
        },
      ]
    
  4. 为指定页面的特定内容进行权限校验

    Umi4提供了useAcess()为权限管理的Hooks函数,并且可以使用Acess组件来包裹指定权限下才可显示的TSX元素

    Acess组件对应的属性如下:

    • accessible (boolean) :是否有权限
    • fallback (React.ReactNode) :无权限时的显示,默认无权限不显示任何内容
    • children (React.ReactNode) :有权限时的显示
    import React from 'react';
    import { useAccess, Acess } from '@umijs/max';
    import { Button } fronm 'antd';
    
    const PageA = (props) => {
      const { foo } = props;
      const access = useAccess();
      if (access.canReadFoo) {
        // 如果可以读取 Foo,则...
      }
    
      return (
        <div>
          <Acess
            accessible={access.canSeeSuperAdmin}
          >
            <Button>Create</Button>
          </Acess>
          TODO
        </div>
      );
    };
    export default PageA;
    

优点

  • 前端可以直接配置路由权限,配置简单

缺点

  • 页面标题修改较为繁琐,需要前后端共同修改
  • 用户不能灵活配置对应角色组的权限

方法二 前端渲染后端传回的动态路由

此处我们使用了Umi中的运行时配置文件,即app.tsx文件。我们需要在该文件导出patchClientRoutes函数,去修改我们现有的路由

步骤

动态路由在app.tsx中配置即可

import { requestAccountGetRoutes } from '@/utils/Account'

let extraRoutes: any[] = [];

// 配置routes
export const patchClientRoutes = ({ routes }) => {
  // 直接修改routes即可,无需返回
}

// 获取routes数据
export const render = (oldRender) => {
  requestAccountGetRoutes().then((res: any) => {
    extraRoutes = JSON.parse(res.data)
    console.log('=====routes======', extraRoutes);
    oldRender()
  })
}

优点

  • 可以灵活配置各个角色的权限,包括页面权限,以及页面下具体按钮的权限
  • 后端可以灵活配置页面的标题

缺点

  • 后端同学工作量较大,权限配置较为繁琐

参考文章:blog.csdn.net/JZH20/artic…