plugin-access控制路由权限

707 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

umi提供了一个可以控制权限的插件plugin-access

插件用法

plugin-access约定在/access.js文件定义路由权限。

文件返回: 该文件默认导出一个函数,函数返回一个对象,函数默认传入initialState,对象里每个数据的值都为一个布尔值,表示这个变量的是否有权限。

函数返回值: 默认返回一个对象,对象的每一个键值就是一条路由,值一般为true或者false,表示是否展示这条路由。

假如有个用户页面,有个用户列表,我们要通过角色去判断用户能不能修改和删除.


// /access.js
export default function(initialState) {

    const {role} = initialState;
    
    return {
        'canEdit': role === "admin",
        
        'canDel': role === "admin",
    }

}


// /user.jsx
import React from 'react';
import { useAccess } from 'umi';
import { Table } from 'antd';

const Page = props => {
  const access = useAccess();
 
  return <>
      <Table columns={[
          {
              title: '姓名',
              dataIndex: 'name',
              key: 'name',
          },
          {
              title: '年龄',
              dataIndex: 'age',
              key: 'age',
          },
          {
              title: '操作',
              dataIndex: 'operates',
              key: '操作',
              render: (text: any, row: any) => (
                 <div>
                     {access?.canEdit && <a>编辑</a>}
                     {access?.canDel && <a>删除</a>}
                 </div>
                 
              )
          },
      ]}/>
  </>;
};

export default PageA;

使用该插件控制路由权限

  1. 获取有权限的路由列表 这个权限列表,我们一般从后端获取,或者通过权限去配置。 access文件传入参数initialState,所以,我们把这个列表存入initialState中,方便获取。
// app.js

export async function getInitialState() {
  const menuAuthList = await request("/getMenuAuthList.json");
  return {
    menuAuthList
  };
}
  1. 写本地路由 配置一个默认的本地静态路由,并在/config/config.ts中routes配置中引入 给路由配置一个access,用来定义每个路由的权限名称。
//  /config/routes/index.ts
export default [
    {
        path: '/demo/welcome',
        name: '欢迎',
        icon: 'smile',
        component: '@/pages/demo/welcome',
        access: 'welcome'
      },
      {
        path: '/demo/form/form-input',
        name: 'antd表单项',
        icon: 'smile',
        component: './demo/form/form-input',
        access: 'formInput'
      },
]
  1. 通过权限列表去过滤本地路由 判断权限列表中是否存在路由中的access,如果有,就将这个权限存入对象,由于路由是一个树状结构,所以我们需要层层递归,去判断每一层的每一个路由的权限。access通过这样的配置就可以很简单的实现针对某些页面的权限控制,只要这个路由是权限文件中返回的某个为true的key值,就会展示出这个路由, 否则会默认渲染 Layout 插件内置的权限错误页面。
import { MENU_SWITCH } from '@/constants';
import route from '../config/routes';

export default function access(initialState) {
  if (MENU_SWITCH) {
    return true;
  } else {
    const { menuAuthList } = initialState || {};
    let accessData = {};
    const tree = (data) => {
      return (data || []).map((item) => {
        const { routes = [], access } = item;
        if (menuAuthList.includes(newAccess)) {
          accessData[access] = true;
        } else {
          accessData[access] = false;
        }
        tree(routes);
      });
    };
    tree(route);
    return accessData;
  }
}