加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – 根据用户角色隐藏一些React组件子项

发布时间:2020-12-15 20:44:59 所属栏目:百科 来源:网络整理
导读:我在React和Redux中编写了一个单页面应用程序(带有Node.js后端). 我想实现基于角色的访问控制,并希望控制应用程序的某些部分(或子部分)的显示. 我将从Node.js获取权限列表,这只是一个具有这种结构的对象: { users: 'read',models: 'write',... dictionaries
我在React和Redux中编写了一个单页面应用程序(带有Node.js后端).

我想实现基于角色的访问控制,并希望控制应用程序的某些部分(或子部分)的显示.

我将从Node.js获取权限列表,这只是一个具有这种结构的对象:

{
  users: 'read',models: 'write',...
  dictionaries: 'none',}

密钥是受保护的资源,

value是此资源的用户权限(以下之一:none,read,write).

我将它存储到redux状态.似乎很容易.

反应路由器路由onEnter / onChange挂钩或redux-auth-wrapper将检查none权限.这似乎也很容易.

但是,对任何组件视图应用读/写权限的最佳方法是什么(例如,如果用户具有{models:’read’}权限,则隐藏模型组件中的编辑按钮).

我找到了this solution并为我的任务改了一点:

class Check extends React.Component {
  static propTypes = {
    resource: React.PropTypes.string.isRequired,permission: React.PropTypes.oneOf(['read','write']),userPermissions: React.PropTypes.object,};

  // Checks that user permission for resource is the same or greater than required
  allowed() {
    const permissions = ['read','write'];
    const { permission,userPermissions } = this.props;
    const userPermission = userPermissions[resource] || 'none';

    return permissions.indexOf(userPermission) >= permissions.indexOf(permission)
  }

  render() {
    if (this.allowed()) return { this.props.children };
  }
}

export default connect(userPermissionsSelector)(Check)

其中userPermissionsSelector将是这样的:(store)=> store.userPermisisons并返回用户权限对象.

然后使用Check包装protected元素:

<Check resource="models" permission="write">
  <Button>Edit model</Button>
</Check>

因此,如果用户没有模型的写入权限,则不会显示该按钮.

有人做过这样的事吗?有比这更“优雅”的解决方案吗?

谢谢!

附:当然,用户权限也将在服务器端进行检查.

好吧,我想我明白你想要什么.我已经做了一些适合我的事情,我喜欢我的方式,但我知道其他可行的解决方案都在那里.

我写的是HOC反应路由器风格.

基本上我有我的PermissionsProvider,我在其中初始化用户权限.我有另一个withPermissions HOC,它将我之前提供的权限注入到我的组件中.

因此,如果我需要检查该特定组件的权限,我可以轻松访问它们.

// PermissionsProvider.js
import React,{ Component } from "react";
import PropTypes from "prop-types";
import hoistStatics from "hoist-non-react-statics";

class PermissionsProvider extends React.Component {
  static propTypes = {
    permissions: PropTypes.array.isRequired,};

  static contextTypes = {
    permissions: PropTypes.array,};

  static childContextTypes = {
    permissions: PropTypes.array.isRequired,};

  getChildContext() {
    // maybe you want to transform the permissions somehow
    // maybe run them through some helpers. situational stuff
    // otherwise just return the object with the props.permissions
    // const permissions = doSomething(this.props.permissions);
    // maybe add some validation methods
    return { permissions: this.props.permissions };
  }

  render() {
    return React.Children.only(this.props.children);
  }
}

const withPermissions = Component => {
  const C = (props,context) => {
    const { wrappedComponentRef,...remainingProps } = props;

    return (
      <Component permissions={context.permissions} {...remainingProps} ref={wrappedComponentRef} />
    );
  };

  C.displayName = `withPermissions(${Component.displayName || Component.name})`;
  C.WrappedComponent = Component;
  C.propTypes = {
    wrappedComponentRef: PropTypes.func
  };

  C.contextTypes = {
    permissions: PropTypes.array.isRequired
  };

  return hoistStatics(C,Component);
};

export { PermissionsProvider as default,withPermissions };

好的,我知道这是很多代码.但这些是HOC(你可以了解更多here).

A higher-order component (HOC) is an advanced technique in React for
reusing component logic. HOCs are not part of the React API,per se.
They are a pattern that emerges from React’s compositional nature.
Concretely,a higher-order component is a function that takes a
component and returns a new component.

基本上我这样做是因为我受到路由器反应的启发.
每当你想知道一些路由的东西,你可以添加装饰器@withRouter,他们将道具注入你的组件.那么为什么不做同样的事呢?

>首先,您必须使用提供程序设置权限
>然后在检查权限的组件上使用withPermissions装饰器

//App render
return (
   <PermissionsProvider permissions={permissions}>
      <SomeStuff />
   </PermissionsProvider>
);

在SomeStuff里面你有一个广泛传播的工具栏来检查权限?

@withPermissions
export default class Toolbar extends React.Component {
  render() {
    const { permissions } = this.props;

    return permissions.canDoStuff ? <RenderStuff /> : <HeCantDoStuff />; 
  }
}

如果您不能使用装饰器,则可以像这样导出工具栏

export default withPermissions(Toolbar);

这是我在实践中展示的代码框:

https://codesandbox.io/s/lxor8v3pkz

笔记:

>我真的非常简化了权限,因为该逻辑来自您的结束,为了演示目的,我简化了它们.>我假设权限是一个数组,这就是为什么我检查HOC中的PropTypes.array>这是一个非常漫长而复杂的答案,我试图用最好的能力表达出来.请不要在这里和那里烧掉我的一些错误:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读