我有一个包含多个组件的React-Redux-KoaJs应用程序。我也没有几个用户角色。现在,我只想显示几个按钮,表格和div以仅显示特定角色,并隐藏其他角色。请记住,我不想隐藏整个组件,而只是部分组件。谁能帮我?预先感谢。
答案 0 :(得分:3)
请注意这一点。如果某些角色的动作很重要,则应始终在后端对其进行验证。更改存储在前端redux中的值很容易,如果没有适当的验证,允许恶意使用角色。
如果您想采取一种可能的方法,是这样的:
function mapStateToProps(state) {
const { user_roles } = state;
return { user_roles };
}
export default connect(mapStateToProps)(YourComponent);
render() {
return (
<div>
{this.props.user_roles.role === "YOUR_ROLE_TO_CHECK" && <ActionsComponent />}
</div>
);
}
仅当角色与所需角色相同时,才会呈现ActionsComponent
。
再次,请始终在后端验证角色!
答案 1 :(得分:3)
您可以按照@Eudald Arranz的建议检查每个组件中的角色或权限。或者,您可以编写一个组件来检查您的权限。例如:
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
const ShowForPermissionComponent = (props) => {
const couldShow = props.userPermissions.includes(props.permission);
return couldShow ? props.children : null;
};
ShowForPermissionComponent.propTypes = {
permission: PropTypes.string.isRequired,
userPermissions: PropTypes.array.isRequired
};
const mapStateToProps = state => ({
userPermissions: state.user.permission //<--- here you will get permissions for your user from Redux store
});
export const ShowForPermission = connect(mapStateToProps)(ShowForPermissionComponent);
,然后您可以像下面这样使用该组件:
import React from 'react';
import { ShowForPermission } from './ShowForPermission';
cons MyComponent = props => {
return (
<div>
<ShowForPermission permission="DELETE">
<button>Delete</button>
</ShowForPermission>
</div>
);
}
答案 2 :(得分:0)
解决此问题的最佳实践是,仅阻止应用程序生成不必要的路由,而是检查每条路由上的当前用户角色,最好仅生成用户有权访问的路由。
所以正常退出是: 要控制整个视图:
const App = () => (
<BrowserRouter history={history}>
<Switch>
<Route path="/Account" component={PrivateAccount} />
<Route path="/Home" component={Home} />
</Switch>
</BrowserRouter>
export default App;
);
基于用户角色的路由:
import { connect } from 'react-redux'
// other imports ...
const App = () => (
<BrowserRouter history={history}>
<Switch>
{
this.props.currentUser.role === 'admin' ?
<>
<Route path="/Account" exact component={PrivateAccount} />
<Route path="/Home" exact component={Home} />
</>
:
<Route path="/Home" exact component={Home} />
}
<Route component={fourOFourErroPage} />
</Switch>
</BrowserRouter>
const mapStateToProps = (state) => {
return {
currentUser: state.currentUser,
}
}
export default connect(mapStateToProps)(App);
因此,具有管理员角色的用户将有权访问“帐户”页面,而对于其他用户,则只能访问“主页”!并且如果任何用户尝试访问其他路由,则会显示404页面错误。 希望我能提供有用的解决方案。
有关此方法的详细信息,您可以在github上查看此仓库:Role-based-access-control with react
仅隐藏演示组件:
{this.props.currentUser.role === 'admin' && <DeleteUser id={this.props.userId} /> }
答案 3 :(得分:0)
我已经在此rbac-react-redux-aspnetcore repository中实现了此功能。 如果有人想将Redux与Context API结合使用,则下面的代码段可能会有所帮助。
export const SecuedLink = ({ resource, text, url }) => {
const userContext = useSelector(state => {
return state.userContext;
});
const isAllowed = checkPermission(resource, userContext);
const isDisabled = checkIsDisabled(resource, userContext);
return (isAllowed && <Link className={isDisabled ? "disable-control" : ""} to={() => url}>{text}</Link>)
}
const getElement = (resource, userContext) => {
return userContext.resources
&& userContext.resources.length > 0
&& userContext.resources.find(element => element.name === resource);
}
export const checkPermission = (resource, userContext) => {
const element = getElement(resource, userContext);
return userContext.isAuthenticated && element != null && element.isAllowed;
}
export const checkIsDisabled = (resource, userContext) => {
const element = getElement(resource, userContext);
return userContext.isAuthenticated && element != null && element.isDisabled;
}
要使用上面的代码段,我们可以像下面这样使用它
<SecuedLink resource='link-post-edit' url={`/post-edit/${post.id}`} text='Edit'></SecuedLink>
<SecuedLink resource='link-post-delete' url={`/post-delete/${post.id}`} text='Delete'></SecuedLink>
因此,根据角色,您不仅可以显示/隐藏元素,还可以启用/禁用它们。权限管理与react-client完全分离,并在数据库中进行管理,因此您不必为了支持新角色和新权限而一次又一次地部署代码。