Ant-design-pro: 动态判断路由权限问题

Created on 18 Oct 2018  ·  10Comments  ·  Source: ant-design/ant-design-pro

问题提出

看很多Issues都提出了菜单和路由权限动态获取的问题,基本都看了一遍,没发现好的路由权限解决问题。菜单权限动态获取可以通过更改BasicLayout.js的方法动态获取,但是路由无法更改,在mock中返回如下结构的menuData,其中的authority并不生效,只有在router.config.js中才生效。

 [
     {
        "path": "/",
        "redirect": "/dashboard/analysis",
        "authority": ['admin', 'user'],
        "exact": true,
      }, 
     {
        "path": "/dashboard",
        "name": "Dashboard",
        "icon": "dashboard",
        "children": [{
          "path": "/dashboard/analysis",
          "name": "分析页",
          "authority": ["user"],
          "exact": true,
       }, {
          "path": "/dashboard/monitor",
          "name": "监控页",
          "authority": ["user"],
          "exact": true,
        }, {
          "path": "/dashboard/workplace",
          "name": "工作台",
          "exact": true,
        }]
      }
]
  • BasicLayout.js改造
componentDidMount 时 增加查询当前菜单
dispatch({
      type: 'global/getMenu',
      payload: localStorage.getItem('antd-pro-authority'),
    })

export default connect(({ global, setting }) => ({
  menuData: global.menuData, // 增加当前菜单
  collapsed: global.collapsed,
  layout: setting.layout,
  ...setting,
}))(BasicLayout);

渲染时
render() {
    const {
      menuData,  // 从props拿到当前menuData
      navTheme,
      layout: PropsLayout,
      children,
      location: { pathname },
    } = this.props;
...

上面的改动可以实现菜单动态获取,路由获取时,不生效,即使不显示工作台菜单,却仍然可以通过http://localhost:8000/dashboard/workplace访问

/**
   * 获取面包屑映射
   * @param {Object} menuData 菜单配置
   */
  getBreadcrumbNameMap() {
    const routerMap = {};
    const {menuData} = this.props
    const mergeMenuAndRouter = data => {
      data.forEach(menuItem => {
        if (menuItem.children) {
          mergeMenuAndRouter(menuItem.children);
        }
        // Reduce memory usage
        routerMap[menuItem.path] = menuItem;
      });
    };
    mergeMenuAndRouter(menuData); // 这里拿props里的menuData
    return routerMap;
  }

目前解决

目前通过subscriptions监控路由暂时解决了路由访问时的问题,但不知道有没有问题

subscriptions: {
    setup({ history }) {
     // 如果没有key且不是首页则返回403,防止里直接输入localhost:8000/dashboard/workplace进行访问
      if(!history.location.key && history.location.pathname !== '/'){
        router.push('/exception/403');
      }
      // Subscribe history(url) change, trigger `load` action if pathname is `/`
      return history.listen(({ pathname, search }) => {
        if (typeof window.ga !== 'undefined') {
          window.ga('send', 'pageview', pathname + search);
        }
      });
    },
  },

期待

官方可否给出一个路由控制的实例,或者是大致思路方案,目前Issues有很多都未完结或者各自解决的

Most helpful comment

既然需求这么多,支持官方出个动态菜单的例子。

All 10 comments

既然需求这么多,支持官方出个动态菜单的例子。

动态菜单的人真的很多,可以设置没有在菜单中显示的路由为 403

动态菜单的人真的很多,可以设置没有在菜单中显示的路由为 403

想在每个路由进入前判断是否在菜单中,不在就返回403,目前在BasicLayout里的componentDidUpdate时做了一下判断,感觉不是很合理,有其它的方法么

重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。

重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。

是说Authorized里的这部分代码么 这个感觉实现有些复杂 一定要在每个菜单里添加authority 数组节点

const checkPermissions = (authority, currentAuthority, target, Exception) => {
  // 没有判定权限.默认查看所有
  // Retirement authority, return target;
  if (!authority) {
    return target;
  }
 ...
}

重写 一下权限路由,没有权限就给返回403好了,现在为 false 的时候默认是放过的。

是说Authorized里的这部分代码么 这个感觉实现有些复杂 一定要在每个菜单里添加authority 数组节点

js const checkPermissions = (authority, currentAuthority, target, Exception) => { // 没有判定权限.默认查看所有 // Retirement authority, return target; if (!authority) { return target; } ... } 按照你的写法能够实现,但是页面刷新完后选择的菜单没有激活(没有被选择的颜色背景)

动态菜单的人真的很多,可以设置没有在菜单中显示的路由为403

想在每个路由进入前判断是否在菜单中,不在就返回403,目前在将BasicLayout里的componentDidUpdate时做了一下判断,感觉不是很合理,有其它的方法么

问一下,你这边最后是如何解决这个问题的,我现在也遇到一样的问题,没有找到好的解决方案。

在 UmiJS3 里面的运行时配置中动态修改路由的 authority 字段,就可以满足你需求

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yjz1004 picture yjz1004  ·  3Comments

yaoleiroyal picture yaoleiroyal  ·  3Comments

zhuanglong picture zhuanglong  ·  3Comments

952425340 picture 952425340  ·  3Comments

ghost picture ghost  ·  3Comments