我在React和Redux中编写了一个单页面应用程序(带有Node.js后端) .
我想实现基于角色的访问控制,并希望控制应用程序的某些部分(或子部分)的显示 .
我将从Node.js获取权限列表,这只是一个具有这种结构的对象:
{
users: 'read',
models: 'write',
...
dictionaries: 'none',
}
key 是受保护的资源,
value 是此资源的用户权限(以下之一: none
, read
, write
) .
我将它存储到redux状态 . 似乎很容易 .
将通过 react-router
routes onEnter/onChange
hooks或 redux-auth-wrapper
检查 none
权限 . 这似乎也很容易 .
但是,将 read/write
权限应用于任何组件视图的最佳方法是什么(例如,如果用户具有 { 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
包装受保护的元素:
<Check resource="models" permission="write">
<Button>Edit model</Button>
</Check>
因此,如果用户没有 models
的 write
权限,则不会显示该按钮 .
有人做过这样的事吗?有比这更“优雅”的解决方案吗?
谢谢!
P.S. 当然也会在服务器端检查用户权限 .
2 回答
@lokuzt建议的方法很棒 .
您可以更进一步,以简化您的代码 .
首先,每个受保护的组件都有一些 requirement 满足渲染 . 您需要定义一个函数,该函数将 requirement 呈现并将当前用户的 credentials 作为参数 . 它必须返回 true 或 false .
此外,我们必须使用ReactJS中的new context API定义HOC (Higher-Order Component) .
现在您可以装饰您的组件:
甚至是第三方组件:
凭据必须由ReactJS上下文API传递:
这是我在github上的扩展implementation .
demo也可用 .
好吧,我想我明白你想要什么 . 我已经做了一些适合我的事情,我喜欢我的方式,但我知道其他可行的解决方案都在那里 .
我写的是HOC反应路由器风格 .
基本上我有 PermissionsProvider 我在哪里初始化用户权限 . 我有另一个 withPermissions HOC,它将我之前提供的权限注入到我的组件中 .
因此,如果我需要检查该特定组件的权限,我可以轻松访问它们 .
好的,我知道这是很多代码 . 但这些是HOC(你可以了解更多here) .
基本上我这样做是因为我受到路由器反应的启发 . 每当你想知道一些路由的东西,你可以添加装饰器 @withRouter ,他们将道具注入你的组件 . So why not do the same thing?
首先,您必须使用提供程序设置权限
然后在检查权限的组件上使用 withPermissions 装饰器
在 SomeStuff 内的某个地方你有一个广泛传播的工具栏来检查权限?
如果您不能使用装饰器,则可以像这样导出工具栏
这是我在实践中展示的代码框:
https://codesandbox.io/s/lxor8v3pkz
笔记:
我真的真的简化了权限,因为这个逻辑来自你的结束,为了演示的目的我简化了它们 .
我假设权限是一个数组,这就是我检查HOC中的PropTypes.array的原因
它's a really long and complicated answer and I tried to articulate at my best ability. Please don' t烧烤我在这里和那里的一些错误:)