Ant-design-pro: Authorized

Created on 3 Sep 2018  ·  16Comments  ·  Source: ant-design/ant-design-pro

pages里有Authorized.js,utils里也有Authorized.js和authority.js,这个是不是应该合一啊?

Most helpful comment

就权限这块我觉得有一些需要改进的地方 @chenshuai2144

  1. src/utils/authority.js
export function getAuthority() {
  let authority = localStorage.getItem('antd-pro-authority');
  if (authority) {
    if (authority.includes('[')) {
      authority = JSON.parse(authority);
    } else {
      authority = [authority];
    }
  }
  // ... 
}

由于login和logout均通过以下函数实现权限更新

// src/pages/User/Model
changeLoginStatus(state, { payload }) {
  setAuthority(payload.currentAuthority);
  return {
    ...state,
    status: payload.status,
    type: payload.type,
  };
},
reloadAuthorized();

// src/utils/Authorized.js
const reloadAuthorized = () => {
  Authorized = RenderAuthorized(getAuthority());
};
// src/util/authority.js
export function setAuthority(authority) {
  return localStorage.setItem('antd-pro-authority', JSON.stringify(authority));
}

会导致登陆后若用户的角色为单个,获取到的是一个包含了经过JSON.stringify处理的字符串的数组,类似[""user""],建议将authority = [authority];改为authority = JSON.parse(authority);authority = [JSON.parse(authority)];,使单角色和多角色的用户保持统一。

2.在src/pages/Authorized.js

const Authorized = RenderAuthorized(['admin', 'user']);

这行代码会强制将权限控制该权限路由的准入权限锁死,不应该是const Authorized = RenderAuthorized(getAuthority());么?

3.在src/pages/Authorized.js

export default ({ children, route, location }) => {
  // ...
  routes.forEach(item => {
    if (Array.isArray(item.route.authority)) {
      authorities = authorities.concat(item.route.authority);
    } else if (typeof item.route.authority === 'string') {
      authorities.push(item.route.authority);
    }
  });
  // ...
  return (
    <Authorized
      authority={authorities.length === 0 ? undefined : uniq(authorities)}
      noMatch={noMatch}
    >
      {children}
    </Authorized>
  );
}

目前官方使用了从外层到当前激活的内层路由进行遍历,然后将权限属性全部填入一个数组然后进行去重处理来判断,这样做有个问题:假如form父级路由的authority设置了['user', 'admin'],而下面的某个具体路由的authority设置成了'admin',本意是指由admin角色的用户可以进入该页面,但实际是只有侧边菜单中的这一项被隐藏了,实际依然可以通过url进行访问。

All 16 comments

pages里的是在路由组件被渲染前进行判定用的,而utils的两个是工具。1.x的时候权限是通过src/router.js文件中的AuthorizedRoute组件来全局控制,2.0将路由改为纯配置文件后,1.x的方案无法使用,只能单独加一个并注入到配置文件中。

就权限这块我觉得有一些需要改进的地方 @chenshuai2144

  1. src/utils/authority.js
export function getAuthority() {
  let authority = localStorage.getItem('antd-pro-authority');
  if (authority) {
    if (authority.includes('[')) {
      authority = JSON.parse(authority);
    } else {
      authority = [authority];
    }
  }
  // ... 
}

由于login和logout均通过以下函数实现权限更新

// src/pages/User/Model
changeLoginStatus(state, { payload }) {
  setAuthority(payload.currentAuthority);
  return {
    ...state,
    status: payload.status,
    type: payload.type,
  };
},
reloadAuthorized();

// src/utils/Authorized.js
const reloadAuthorized = () => {
  Authorized = RenderAuthorized(getAuthority());
};
// src/util/authority.js
export function setAuthority(authority) {
  return localStorage.setItem('antd-pro-authority', JSON.stringify(authority));
}

会导致登陆后若用户的角色为单个,获取到的是一个包含了经过JSON.stringify处理的字符串的数组,类似[""user""],建议将authority = [authority];改为authority = JSON.parse(authority);authority = [JSON.parse(authority)];,使单角色和多角色的用户保持统一。

2.在src/pages/Authorized.js

const Authorized = RenderAuthorized(['admin', 'user']);

这行代码会强制将权限控制该权限路由的准入权限锁死,不应该是const Authorized = RenderAuthorized(getAuthority());么?

3.在src/pages/Authorized.js

export default ({ children, route, location }) => {
  // ...
  routes.forEach(item => {
    if (Array.isArray(item.route.authority)) {
      authorities = authorities.concat(item.route.authority);
    } else if (typeof item.route.authority === 'string') {
      authorities.push(item.route.authority);
    }
  });
  // ...
  return (
    <Authorized
      authority={authorities.length === 0 ? undefined : uniq(authorities)}
      noMatch={noMatch}
    >
      {children}
    </Authorized>
  );
}

目前官方使用了从外层到当前激活的内层路由进行遍历,然后将权限属性全部填入一个数组然后进行去重处理来判断,这样做有个问题:假如form父级路由的authority设置了['user', 'admin'],而下面的某个具体路由的authority设置成了'admin',本意是指由admin角色的用户可以进入该页面,但实际是只有侧边菜单中的这一项被隐藏了,实际依然可以通过url进行访问。

写的很棒,有没有兴趣提个 pr,我们加入到文档中

怎么做?萌新一枚 没提过pr

关于最后一点,我个人觉得可以用“交集”来处理,就是lodash提供的intersection函数,并且参数中剔除undefined的那些项

// ...
import intersection from 'lodash/intersection';
// ...
export default ({ children, route, location }) => {
  // ...
  let authorities = [];
  routes.forEach(item => {
    if (Array.isArray(item.route.authority) && item.route.authority.length) {
      authorities.push(item.route.authority);
    } else if (typeof item.route.authority === 'string' && item.route.authority) {
      authorities.push([item.route.authority]);
    }
  });
  // ...
  return (
    <Authorized
      authority={authorities.length === 0 ? undefined : intersection(...authorities)}
      noMatch={noMatch}
    >
      {children}
    </Authorized>
  );
};

@Tan90Qian 我clone的新项目,启动起来,怎么直接就进入了首页了?而不是进入登录页面了?

@CasperMXP 因为getAuthority函数在localStorage中不存在目标字段的时候是当作admin处理的。方便功能预览,而路由配置中有这样一段{ path: '/', redirect: '/dashboard/analysis' },,所以会直接当作已登陆来处理

@Tan90Qian 明白了,谢谢。咨询哈你官网文档权限设置
path: '/form', icon: 'form', name: 'form', children: [{ path: '/form/basic-form', name: 'basicform', component: './Forms/BasicForm', }
用的是children而实际代码中router.config.js中用的routes,这个是怎么回事了?

2.0刚上没几天,文档更新不及时

@Tan90Qian 能不能分析哈router.config.js怎么被解析的了,我看了半天只知道被config.js读取了,谢谢了。

@Tan90Qianhttps://github.com/ant-design/ant-design-pro-site 这里 pr 就好了

@Tan90Qian @chenshuai2144 我按照文档讲的将menuData从mock中读取,但是加了权限字段,设置成admin,admin账户登录进去也不显示,是不是menuData数据结构不对?大佬些。

export default {
  'GET /api/menus': [
    {
      path: '/dashboard',
      name: 'dashboard',
      icon: 'dashboard',
      locale: 'menu.dashboard',
      authority:["admin"],
      children: [
        {
          path: '/dashboard/analysis',
          name: 'analysis',
          locale: 'menu.dashboard.analysis',
        },
        {
          path: '/dashboard/monitor',
          name: 'monitor',
          locale: 'menu.dashboard.monitor',
        },
        {
          path: '/dashboard/workplace',
          name: 'workplace',
          locale: 'menu.dashboard.monitor',
        },
      ],
    },
    ]
}

@chenshuai2144 我之前在这里提了:https://github.com/ant-design/ant-design-pro/pull/2170
check有2个出错了,不知道什么原因。还需要在ant-design-pro-site重新提么?

需要的。ant-design-pro-site 是文档站

@CasperMXP 返回 router.config.js 里面的内容就好了

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhuanglong picture zhuanglong  ·  3Comments

952425340 picture 952425340  ·  3Comments

happier2 picture happier2  ·  3Comments

kaoding picture kaoding  ·  3Comments

gaoqiang19514 picture gaoqiang19514  ·  3Comments