角色权限系统

角色权限系统(RBAC)最全设计:Java 落地 + 表结构 + 接口方案

我给你企业级最标准、面试必问、开发直接用RBAC 权限系统设计,从表结构 → 业务模型 → Java 实现 → 前端控制,一次性讲透。

你做后台管理、RAG 知识库权限、用户权限隔离,直接照搬这套


一、一句话记住:权限系统 = RBAC 模型

RBAC = Role-Based Access Control(基于角色的访问控制)

核心思想:

用户 ← 多对多 → 角色 ← 多对多 → 权限

  • 一个用户有多个角色
  • 一个角色有多个权限
  • 权限 = 菜单/按钮/接口/数据

二、最经典 5 张表(生产标准表结构)

这 5 张表能满足 99% 后台系统。

sql 复制代码
-- 1. 用户表
CREATE TABLE sys_user (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL UNIQUE,
  password VARCHAR(100) NOT NULL,
  nickname VARCHAR(50),
  is_admin TINYINT DEFAULT 0 COMMENT '1=超级管理员',
  create_time DATETIME DEFAULT NOW()
);

-- 2. 角色表
CREATE TABLE sys_role (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  role_name VARCHAR(50) NOT NULL,
  role_code VARCHAR(50) NOT NULL UNIQUE,
  remark VARCHAR(255)
);

-- 3. 权限表
CREATE TABLE sys_permission (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  perm_name VARCHAR(50) NOT NULL,
  perm_code VARCHAR(100) NOT NULL UNIQUE COMMENT '如 user:list, doc:upload',
  perm_type VARCHAR(20) COMMENT 'menu/button/api',
  parent_id BIGINT DEFAULT 0,
  sort INT DEFAULT 0
);

-- 4. 用户-角色关联表
CREATE TABLE sys_user_role (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  role_id BIGINT NOT NULL
);

-- 5. 角色-权限关联表
CREATE TABLE sys_role_perm (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  role_id BIGINT NOT NULL,
  perm_id BIGINT NOT NULL
);

-- 初始化数据
INSERT INTO sys_user (username,password,is_admin) VALUES ('admin','123456',1);
INSERT INTO sys_role (role_name,role_code) VALUES ('管理员','admin'),('访客','guest');
INSERT INTO sys_permission (perm_name,perm_code) VALUES
('用户列表','user:list'),('新增用户','user:add'),
('知识库查看','doc:view'),('文档上传','doc:upload');

三、权限三种粒度(你一定会用到)

1. 菜单权限(看得见哪些菜单)

2. 按钮权限(新增、删除、编辑)

3. 接口权限(API 能不能调用)

4. 数据权限(可选高级:只能看自己/部门/全部数据)


四、核心设计逻辑(最关键)

1. 登录流程

  1. 用户登录

  2. 查用户 → 查角色 → 查权限

  3. 权限编码集合 存入 Redis

    复制代码
    user:1001:permissions → ["user:list","user:add","doc:view"]

2. 鉴权流程

  • 前端:按钮/菜单根据权限码显示/隐藏
  • 后端:接口加 @PreAuthorize("hasPermission('user:add')")
  • 拦截器:从 Redis 取用户权限 → 判断是否包含当前接口权限码

五、Java 实现(SpringBoot + Security 最标准)

1. 核心步骤

  1. 登录时加载 用户所有权限
  2. 存入 Redis
  3. 每次请求走拦截器鉴权

2. 核心代码(获取用户权限)

java 复制代码
// 根据用户ID查所有权限(用户→角色→权限)
Set<String> getPermissionCodesByUserId(Long userId) {
    // 1. 查用户角色
    List<Long> roleIds = userRoleMapper.listByUserId(userId);
    // 2. 查角色权限
    Set<String> permCodes = rolePermMapper.listPermCodesByRoleIds(roleIds);
    return permCodes;
}

3. Redis 存储权限

复制代码
key: user:{userId}:permissions
value: Set<String> 权限编码

4. 接口鉴权(注解/拦截器)

java 复制代码
@GetMapping("/user/list")
@PreAuthorize("hasPermission('user:list')")
public Result list() {
    return userService.list();
}

六、前端权限控制(按钮/菜单)

vue 复制代码
<!-- 按钮权限 -->
<el-button v-if="hasPerm('user:add')">新增用户</el-button>
js 复制代码
// 判断是否有权限
hasPerm(permCode) {
  return userPermissions.includes(permCode);
}

七、超级管理员怎么设计?

复制代码
if (user.isAdmin == true) {
    // 直接拥有所有权限
    return ALL_PERMISSIONS;
}

八、RBAC 版本演进(面试加分)

  • RBAC0:基础版(用户-角色-权限)
  • RBAC1:角色继承(管理员继承普通角色权限)
  • RBAC2:角色约束(互斥角色、最大人数)
  • RBAC3:最完整(RBAC1 + RBAC2)

企业 99% 用 RBAC0


九、你做 RAG 系统权限怎么用?

直接套:

  • 角色:管理员、编辑、访客
  • 权限:知识库查看、文档上传、问答、删除文档
  • 用户 → 角色 → 权限
  • 问答/检索时:只能检索当前用户有权限的文档

十、一句话总结(背这个)

用户绑定角色,角色绑定权限,登录查权限存入Redis,前端按钮判断、后端接口判断。


相关推荐
ZKNOW甄知科技2 年前
需求管理秘籍:从混乱到有序,让你的项目高效运转
运维·项目管理·配置·权限管理·软件设计·运维管理·角色管理·角色权限·敏捷