2、RBAC0 权限系统详细设计与实现指南

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

目录

  1. RBAC0 模型核心概念
  2. 数据库表结构设计
  3. 工作流程详解
  4. Java 实现示例(含详细中文注释)
  5. API 使用示例
  6. 测试用例验证

一、RBAC0 模型核心概念

1.1 什么是 RBAC0?

RBAC0(Role-Based Access Control Level 0)是 RBAC 模型的基础版本,包含三个核心实体:

  • 用户(User):系统使用者
  • 角色(Role):权限的集合,代表某种职能
  • 权限(Permission):对资源的操作能力

1.2 核心关系

  • 用户 ↔ 角色:多对多关系(一个用户可拥有多个角色,一个角色可分配给多个用户)
  • 角色 ↔ 权限:多对多关系(一个角色可拥有多个权限,一个权限可分配给多个角色)

1.3 形象类比

公司组织架构

  • 用户 = 员工(张三、李四)
  • 角色 = 职位(开发工程师、产品经理、HR)
  • 权限 = 工作职责(写代码、查看需求文档、管理员工信息)

当新员工入职时,只需分配对应职位(角色),自动获得该职位的所有工作职责(权限)


二、数据库表结构设计

2.1 表结构总览

表名说明关系
sys_user用户表-
sys_role角色表-
sys_permission权限表-
sys_user_role用户-角色关联表用户 ↔ 角色
sys_role_permission角色-权限关联表角色 ↔ 权限

2.2 详细表结构

2.2.1 用户表 (sys_user)
CREATE TABLE `sys_user` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `username` VARCHAR(50) NOT NULL COMMENT '用户名(唯一)',
  `password` VARCHAR(100) NOT NULL COMMENT '密码(加密存储)',
  `real_name` VARCHAR(50) NOT NULL COMMENT '真实姓名',
  `email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
  `phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
  `status` TINYINT DEFAULT 1 COMMENT '状态:1-正常,0-禁用',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
2.2.2 角色表 (sys_role)
CREATE TABLE `sys_role` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '角色ID',
  `role_code` VARCHAR(50) NOT NULL COMMENT '角色编码(唯一,用于程序识别)',
  `role_name` VARCHAR(50) NOT NULL COMMENT '角色名称(用于显示)',
  `description` VARCHAR(200) DEFAULT NULL COMMENT '角色描述',
  `status` TINYINT DEFAULT 1 COMMENT '状态:1-正常,0-禁用',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_role_code` (`role_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
2.2.3 权限表 (sys_permission)
CREATE TABLE `sys_permission` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '权限ID',
  `permission_code` VARCHAR(100) NOT NULL COMMENT '权限编码(唯一,用于程序识别)',
  `permission_name` VARCHAR(50) NOT NULL COMMENT '权限名称(用于显示)',
  `resource_type` VARCHAR(20) NOT NULL COMMENT '资源类型:MENU-菜单,BUTTON-按钮,API-接口',
  `resource_path` VARCHAR(200) DEFAULT NULL COMMENT '资源路径(如:/api/user/list)',
  `description` VARCHAR(200) DEFAULT NULL COMMENT '权限描述',
  `status` TINYINT DEFAULT 1 COMMENT '状态:1-正常,0-禁用',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_permission_code` (`permission_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表';
2.2.4 用户-角色关联表 (sys_user_role)
CREATE TABLE `sys_user_role` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '关联ID',
  `user_id` BIGINT NOT NULL COMMENT '用户ID',
  `role_id` BIGINT NOT NULL COMMENT '角色ID',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_user_role` (`user_id`, `role_id`), -- 防止重复分配
  KEY `idx_user_id` (`user_id`),
  KEY `idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户-角色关联表';
2.2.5 角色-权限关联表 (sys_role_permission)
CREATE TABLE `sys_role_permission` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '关联ID',
  `role_id` BIGINT NOT NULL COMMENT '角色ID',
  `permission_id` BIGINT NOT NULL COMMENT '权限ID',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_role_permission` (`role_id`, `permission_id`), -- 防止重复分配
  KEY `idx_role_id` (`role_id`),
  KEY `idx_permission_id` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色-权限关联表';

2.3 示例数据

-- 插入用户
INSERT INTO sys_user (username, password, real_name, email) 
VALUES ('zhangsan', 'encrypted_password', '张三', 'zhangsan@example.com');

-- 插入角色
INSERT INTO sys_role (role_code, role_name, description) 
VALUES ('DEVELOPER', '开发工程师', '负责系统开发'),
       ('PRODUCT_MANAGER', '产品经理', '负责产品需求管理');

-- 插入权限
INSERT INTO sys_permission (permission_code, permission_name, resource_type, resource_path) 
VALUES ('USER_VIEW', '查看用户', 'API', '/api/user/list'),
       ('USER_EDIT', '编辑用户', 'API', '/api/user/update'),
       ('PRODUCT_VIEW', '查看产品', 'API', '/api/product/list');

-- 用户-角色关联(张三拥有开发工程师角色)
INSERT INTO sys_user_role (user_id, role_id) 
VALUES (1, 1);

-- 角色-权限关联(开发工程师拥有查看用户权限)
INSERT INTO sys_role_permission (role_id, permission_id) 
VALUES (1, 1);

三、RBAC0 工作流程详解

3.1 权限分配流程

管理员系统数据库创建角色(开发工程师)插入sys_role表创建权限(查看用户)插入sys_permission表分配权限给角色插入sys_role_permission表创建用户(张三)插入sys_user表分配角色给用户插入sys_user_role表管理员系统数据库

3.2 权限验证流程

用户API接口权限服务数据库请求 /api/user/list检查用户是否有 USER_VIEW 权限查询用户所有角色返回角色列表查询角色对应的权限返回权限列表返回权限检查结果返回用户列表数据返回403错误alt[有权限][无权限]用户API接口权限服务数据库

3.3 核心验证逻辑

  1. 获取当前用户ID
  2. 查询用户关联的所有角色
  3. 查询这些角色关联的所有权限
  4. 检查目标权限是否在权限列表中

四、Java 实现示例(含详细中文注释)

4.1 实体类定义

用户实体
/**
 * 用户实体类
 * 对应数据库表:sys_user
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    /**
     * 用户ID,主键
     */
    private Long id;
    
    /**
     * 用户名,唯一标识,用于登录
     */
    private String username;
    
    /**
     * 密码,加密存储
     */
    private String password;
    
    /**
     * 真实姓名,用于显示
     */
    private String realName;
    
    /**
     * 邮箱地址
     */
    private String email;
    
    /**
     * 手机号码
     */
    private String phone;
    
    /**
     * 用户状态:1-正常,0-禁用
     */
    private Integer status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}
角色实体
/**
 * 角色实体类
 * 对应数据库表:sys_role
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Role {
    /**
     * 角色ID,主键
     */
    private Long id;
    
    /**
     * 角色编码,唯一标识,用于程序中识别角色
     * 例如:ADMIN, DEVELOPER, PRODUCT_MANAGER
     */
    private String roleCode;
    
    /**
     * 角色名称,用于界面显示
     * 例如:管理员、开发工程师、产品经理
     */
    private String roleName;
    
    /**
     * 角色描述,说明角色的职责
     */
    private String description;
    
    /**
     * 角色状态:1-正常,0-禁用
     */
    private Integer status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}
权限实体
/**
 * 权限实体类
 * 对应数据库表:sys_permission
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Permission {
    /**
     * 权限ID,主键
     */
    private Long id;
    
    /**
     * 权限编码,唯一标识,用于程序中识别权限
     * 例如:USER_VIEW, USER_EDIT, PRODUCT_VIEW
     */
    private String permissionCode;
    
    /**
     * 权限名称,用于界面显示
     * 例如:查看用户、编辑用户、查看产品
     */
    private String permissionName;
    
    /**
     * 资源类型:
     * MENU - 菜单权限
     * BUTTON - 按钮权限  
     * API - 接口权限
     */
    private String resourceType;
    
    /**
     * 资源路径,对于API权限就是具体的URL路径
     * 例如:/api/user/list, /api/product/update
     */
    private String resourcePath;
    
    /**
     * 权限描述,说明权限的具体作用
     */
    private String description;
    
    /**
     * 权限状态:1-正常,0-禁用
     */
    private Integer status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}

4.2 Mapper 接口(MyBatis)

用户角色关联查询
/**
 * 用户Mapper接口
 * 负责用户相关的数据库操作
 */
@Mapper
public interface UserMapper {
    
    /**
     * 根据用户ID查询用户基本信息
     * @param userId 用户ID
     * @return 用户对象
     */
    User selectById(Long userId);
    
    /**
     * 根据用户名查询用户(用于登录)
     * @param username 用户名
     * @return 用户对象
     */
    User selectByUsername(String username);
    
    /**
     * 根据用户ID查询用户关联的所有角色ID列表
     * 通过 sys_user_role 关联表查询
     * @param userId 用户ID
     * @return 角色ID列表
     */
    List<Long> selectRoleIdsByUserId(Long userId);
}
角色权限关联查询
/**
 * 角色Mapper接口
 * 负责角色相关的数据库操作
 */
@Mapper
public interface RoleMapper {
    
    /**
     * 根据角色ID列表查询角色基本信息
     * @param roleIds 角色ID列表
     * @return 角色列表
     */
    List<Role> selectByIds(@Param("roleIds") List<Long> roleIds);
    
    /**
     * 根据角色ID列表查询这些角色关联的所有权限ID列表
     * 通过 sys_role_permission 关联表查询
     * @param roleIds 角色ID列表
     * @return 权限ID列表
     */
    List<Long> selectPermissionIdsByRoleIds(@Param("roleIds") List<Long> roleIds);
}
权限查询
/**
 * 权限Mapper接口
 * 负责权限相关的数据库操作
 */
@Mapper
public interface PermissionMapper {
    
    /**
     * 根据权限ID列表查询权限基本信息
     * @param permissionIds 权限ID列表
     * @return 权限列表
     */
    List<Permission> selectByIds(@Param("permissionIds") List<Long> permissionIds);
    
    /**
     * 根据权限编码查询权限
     * @param permissionCode 权限编码
     * @return 权限对象
     */
    Permission selectByCode(String permissionCode);
}

4.3 权限服务核心实现

/**
 * RBAC0权限服务实现类
 * 负责权限的核心业务逻辑处理
 */
@Service
@Slf4j
public class Rbac0PermissionService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    /**
     * 检查用户是否拥有指定权限
     * 这是RBAC0模型的核心验证方法
     * 
     * 验证流程:
     * 1. 根据用户ID获取用户关联的角色ID列表
     * 2. 根据角色ID列表获取这些角色关联的权限ID列表
     * 3. 根据权限ID列表获取权限编码列表
     * 4. 检查目标权限编码是否在权限编码列表中
     * 
     * @param userId 用户ID
     * @param permissionCode 目标权限编码(如:USER_VIEW)
     * @return true-拥有权限,false-无权限
     */
    public boolean hasPermission(Long userId, String permissionCode) {
        log.info("开始检查用户权限: userId={}, permissionCode={}", userId, permissionCode);
        
        try {
            // 步骤1: 获取用户关联的角色ID列表
            List<Long> roleIds = userMapper.selectRoleIdsByUserId(userId);
            log.debug("用户关联的角色ID列表: {}", roleIds);
            
            // 如果用户没有任何角色,直接返回无权限
            if (CollectionUtils.isEmpty(roleIds)) {
                log.warn("用户没有分配任何角色,userId={}", userId);
                return false;
            }
            
            // 步骤2: 获取角色关联的权限ID列表
            List<Long> permissionIds = roleMapper.selectPermissionIdsByRoleIds(roleIds);
            log.debug("角色关联的权限ID列表: {}", permissionIds);
            
            // 如果角色没有任何权限,直接返回无权限
            if (CollectionUtils.isEmpty(permissionIds)) {
                log.warn("角色没有分配任何权限,roleIds={}", roleIds);
                return false;
            }
            
            // 步骤3: 获取权限编码列表
            List<Permission> permissions = permissionMapper.selectByIds(permissionIds);
            Set<String> permissionCodes = permissions.stream()
                    .map(Permission::getPermissionCode)
                    .collect(Collectors.toSet());
            log.debug("用户拥有的权限编码列表: {}", permissionCodes);
            
            // 步骤4: 检查目标权限是否存在
            boolean hasPermission = permissionCodes.contains(permissionCode);
            log.info("权限检查结果: userId={}, permissionCode={}, result={}", 
                    userId, permissionCode, hasPermission);
            
            return hasPermission;
            
        } catch (Exception e) {
            log.error("权限检查发生异常", e);
            // 异常情况下默认返回无权限,保证安全性
            return false;
        }
    }
    
    /**
     * 获取用户拥有的所有权限编码列表
     * 通常用于前端菜单渲染或批量权限检查
     * 
     * @param userId 用户ID
     * @return 权限编码集合
     */
    public Set<String> getUserPermissionCodes(Long userId) {
        log.info("获取用户权限列表: userId={}", userId);
        
        try {
            // 获取用户角色ID列表
            List<Long> roleIds = userMapper.selectRoleIdsByUserId(userId);
            if (CollectionUtils.isEmpty(roleIds)) {
                return Collections.emptySet();
            }
            
            // 获取权限ID列表
            List<Long> permissionIds = roleMapper.selectPermissionIdsByRoleIds(roleIds);
            if (CollectionUtils.isEmpty(permissionIds)) {
                return Collections.emptySet();
            }
            
            // 获取权限编码集合
            List<Permission> permissions = permissionMapper.selectByIds(permissionIds);
            return permissions.stream()
                    .map(Permission::getPermissionCode)
                    .collect(Collectors.toSet());
                    
        } catch (Exception e) {
            log.error("获取用户权限列表发生异常", e);
            return Collections.emptySet();
        }
    }
    
    /**
     * 批量检查用户是否拥有多个权限
     * 用于需要同时检查多个权限的场景
     * 
     * @param userId 用户ID
     * @param permissionCodes 权限编码列表
     * @return 权限检查结果映射(权限编码 -> 是否拥有)
     */
    public Map<String, Boolean> checkPermissions(Long userId, List<String> permissionCodes) {
        // 先获取用户所有权限
        Set<String> userPermissions = getUserPermissionCodes(userId);
        
        // 构建结果映射
        Map<String, Boolean> result = new HashMap<>();
        for (String permissionCode : permissionCodes) {
            result.put(permissionCode, userPermissions.contains(permissionCode));
        }
        
        return result;
    }
}

4.4 权限拦截器实现

/**
 * 权限拦截器
 * 在请求到达Controller之前进行权限验证
 */
@Component
public class PermissionInterceptor implements HandlerInterceptor {
    
    @Autowired
    private Rbac0PermissionService permissionService;
    
    /**
     * 在请求处理之前进行权限检查
     * 
     * @param request 当前HTTP请求
     * @param response HTTP响应
     * @param handler 处理器(Controller方法)
     * @return true-放行,false-拦截
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        
        // 1. 获取当前登录用户ID(假设已通过认证)
        Long currentUserId = getCurrentUserId(request);
        if (currentUserId == null) {
            // 未登录用户,返回401
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("未登录");
            return false;
        }
        
        // 2. 获取当前请求需要的权限编码
        // 这里通过自定义注解@RequirePermission获取
        String requiredPermission = getRequiredPermission(handler);
        if (requiredPermission == null) {
            // 没有权限要求,直接放行
            return true;
        }
        
        // 3. 检查用户是否拥有该权限
        boolean hasPermission = permissionService.hasPermission(currentUserId, requiredPermission);
        if (!hasPermission) {
            // 无权限,返回403
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("无权访问");
            return false;
        }
        
        // 4. 有权限,放行
        return true;
    }
    
    /**
     * 从请求中获取当前用户ID
     * 实际项目中通常从JWT Token或Session中获取
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        // 简化实现:从请求头获取
        String userIdStr = request.getHeader("X-User-Id");
        if (StringUtils.hasText(userIdStr)) {
            try {
                return Long.parseLong(userIdStr);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    /**
     * 从处理器(Controller方法)中获取需要的权限编码
     * 通过解析@RequirePermission注解实现
     */
    private String getRequiredPermission(Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RequirePermission annotation = handlerMethod.getMethodAnnotation(RequirePermission.class);
            if (annotation != null) {
                return annotation.value();
            }
        }
        return null;
    }
}

4.5 自定义权限注解

/**
 * 权限要求注解
 * 用于标记Controller方法需要的权限
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequirePermission {
    
    /**
     * 需要的权限编码
     * 例如:@RequirePermission("USER_VIEW")
     */
    String value();
}

五、API 使用示例

5.1 Controller 层使用

/**
 * 用户管理Controller
 * 演示如何使用权限注解
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    /**
     * 查询用户列表接口
     * 需要 USER_VIEW 权限
     */
    @GetMapping("/list")
    @RequirePermission("USER_VIEW") // 添加权限注解
    public Result<List<UserDTO>> getUserList() {
        List<UserDTO> users = userService.getAllUsers();
        return Result.success(users);
    }
    
    /**
     * 更新用户信息接口
     * 需要 USER_EDIT 权限
     */
    @PostMapping("/update")
    @RequirePermission("USER_EDIT") // 添加权限注解
    public Result<Void> updateUser(@RequestBody UpdateUserRequest request) {
        userService.updateUser(request);
        return Result.success();
    }
    
    /**
     * 获取当前用户信息接口
     * 不需要特殊权限,所有登录用户都可以访问
     */
    @GetMapping("/current")
    public Result<UserDTO> getCurrentUser() {
        UserDTO currentUser = userService.getCurrentUser();
        return Result.success(currentUser);
    }
}

5.2 服务层权限检查

/**
 * 用户服务实现类
 * 在服务层也可以进行权限检查
 */
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private Rbac0PermissionService permissionService;
    
    @Override
    public void deleteUser(Long userId, Long operatorId) {
        // 在删除操作前检查操作者权限
        if (!permissionService.hasPermission(operatorId, "USER_DELETE")) {
            throw new AccessDeniedException("无权删除用户");
        }
        
        // 执行删除逻辑
        userMapper.deleteById(userId);
    }
}

六、测试用例验证

6.1 单元测试

/**
 * RBAC0权限服务测试类
 */
@SpringBootTest
class Rbac0PermissionServiceTest {
    
    @Autowired
    private Rbac0PermissionService permissionService;
    
    @Test
    void testHasPermission_WhenUserHasPermission_ShouldReturnTrue() {
        // 准备数据:用户ID=1,拥有USER_VIEW权限
        
        // 执行权限检查
        boolean result = permissionService.hasPermission(1L, "USER_VIEW");
        
        // 验证结果
        assertTrue(result, "用户应该拥有USER_VIEW权限");
    }
    
    @Test
    void testHasPermission_WhenUserHasNoPermission_ShouldReturnFalse() {
        // 准备数据:用户ID=1,没有USER_EDIT权限
        
        // 执行权限检查
        boolean result = permissionService.hasPermission(1L, "USER_EDIT");
        
        // 验证结果
        assertFalse(result, "用户不应该拥有USER_EDIT权限");
    }
    
    @Test
    void testGetUserPermissionCodes_ShouldReturnCorrectPermissions() {
        // 执行获取权限列表
        Set<String> permissions = permissionService.getUserPermissionCodes(1L);
        
        // 验证结果
        assertTrue(permissions.contains("USER_VIEW"), "应该包含USER_VIEW权限");
        assertFalse(permissions.contains("USER_EDIT"), "不应该包含USER_EDIT权限");
        assertEquals(1, permissions.size(), "应该只有1个权限");
    }
}

6.2 集成测试场景

场景1:正常权限访问

  • 用户:张三(ID=1)
  • 角色:开发工程师(ID=1)
  • 权限:USER_VIEW(ID=1)
  • 请求:GET /api/user/list
  • 预期:返回200,成功获取用户列表

场景2:无权限访问

  • 用户:张三(ID=1)
  • 角色:开发工程师(ID=1)
  • 权限:USER_VIEW(ID=1)
  • 请求:POST /api/user/update
  • 预期:返回403,无权访问

场景3:用户无角色

  • 用户:李四(ID=2)
  • 角色:无
  • 请求:GET /api/user/list
  • 预期:返回403,无权访问

总结

RBAC0 模型虽然简单,但却是权限系统的基础。通过合理的数据库设计和清晰的工作流程,可以构建一个安全、可维护的权限控制系统。关键要点:

  1. 数据库设计:五张核心表,通过关联表实现多对多关系
  2. 权限验证:用户 → 角色 → 权限的链式查询
  3. 安全原则:后端必须进行权限验证,不能依赖前端控制
  4. 性能考虑:适当使用缓存,避免频繁数据库查询
  5. 扩展性:为后续升级到 RBAC1/RBAC2 预留设计空间

这个实现方案可以直接应用于中小型项目,对于大型项目可以在此基础上增加缓存、异步处理等优化措施。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值