角色权限系统(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. 登录流程
-
用户登录
-
查用户 → 查角色 → 查权限
-
把权限编码集合 存入 Redis
user:1001:permissions → ["user:list","user:add","doc:view"]
2. 鉴权流程
- 前端:按钮/菜单根据权限码显示/隐藏
- 后端:接口加 @PreAuthorize("hasPermission('user:add')")
- 拦截器:从 Redis 取用户权限 → 判断是否包含当前接口权限码
五、Java 实现(SpringBoot + Security 最标准)
1. 核心步骤
- 登录时加载 用户所有权限
- 存入 Redis
- 每次请求走拦截器鉴权
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,前端按钮判断、后端接口判断。