You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需逐个控制函数实现权限校验?React RBAC方案咨询

无侵入式RBAC操作权限校验实现方案

一、核心权限校验工具层

先实现全局统一的权限判断逻辑,避免重复代码:

// src/utils/permission.js
import { useContext } from 'react';
import { AuthContext } from '../contexts/AuthContext';

export const usePermission = () => {
  const { user } = useContext(AuthContext);
  const userPermissions = user?.permissions || [];

  // 判断是否拥有指定操作权限
  const hasPermission = (action) => {
    return userPermissions.includes(action);
  };

  return { hasPermission };
};

二、封装权限控制的通用按钮组件

替代原生MUI Button,自动处理权限校验,同时解决禁用后可点击的问题:

// src/components/PermissionButton.js
import { Button } from '@mui/material';
import { usePermission } from '../utils/permission';

const PermissionButton = ({ action, children, ...props }) => {
  const { hasPermission } = usePermission();
  const isAllowed = hasPermission(action);

  // 无权限时禁用并添加防点击样式,彻底阻止交互
  const buttonProps = isAllowed
    ? props
    : {
        ...props,
        disabled: true,
        sx: { ...props.sx, pointerEvents: 'none', opacity: 0.6 }
      };

  // 也可选择无权限时直接隐藏组件,替换上面的return即可
  // if (!isAllowed) return null;

  return <Button {...buttonProps}>{children}</Button>;
};

export default PermissionButton;

使用示例:

<PermissionButton action="add" onClick={addData}>新增设备</PermissionButton>
<PermissionButton action="edit" onClick={editData}>编辑设备</PermissionButton>
<PermissionButton action="delete" onClick={deleteData}>删除设备</PermissionButton>

三、函数级权限拦截高阶函数

对业务操作函数做统一包装,无需逐个加if判断:

// src/utils/permissionHOC.js
import { usePermission } from './permission';
import { useSnackbar } from '@mui/material';

// 高阶函数:传入权限标识,返回包装后的函数
export const withPermission = (action) => (fn) => {
  const { hasPermission } = usePermission();
  const { enqueueSnackbar } = useSnackbar();

  return (...args) => {
    if (!hasPermission(action)) {
      enqueueSnackbar('无此操作权限', { variant: 'error' });
      return;
    }
    // 有权限时执行原函数
    return fn(...args);
  };
};

使用示例:

import { withPermission } from '../utils/permissionHOC';

const DevicesPage = () => {
  // 原业务函数
  const addData = () => { /* 新增设备逻辑 */ };
  const editData = () => { /* 编辑设备逻辑 */ };
  const deleteData = () => { /* 删除设备逻辑 */ };

  // 用高阶函数包装,自动添加权限校验
  const authorizedAdd = withPermission('add')(addData);
  const authorizedEdit = withPermission('edit')(editData);
  const authorizedDelete = withPermission('delete')(deleteData);

  return (
    <>
      <PermissionButton action="add" onClick={authorizedAdd}>新增设备</PermissionButton>
      {/* 即使使用普通按钮,点击也会被权限拦截 */}
      <Button onClick={authorizedEdit}>编辑设备</Button>
    </>
  );
};

四、补充:彻底解决MUI Button禁用交互问题

如果封装组件后仍有问题,可全局添加CSS样式确保禁用状态完全不可交互:

/* src/index.css */
.MuiButton-disabled {
  pointer-events: none !important;
  cursor: not-allowed !important;
}

内容的提问来源于stack exchange,提问作者Furkan YIlmaZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:53:31