RBAC 权限管理(思路)
注意
- JWT 中不要存储太多信息
- 关于权限:只有添加了权限守卫的接口才会被拦截
- 登录后返回用户信息和角色信息,此角色信息只是给前端用的,后端的角色权限还需要从 jwt 中解析用户信息后再次请求接口查询角色信息(此步生产环境则需要在 redis 中缓存)
实体表字段设计
- 用户表
存储用户基础信息,核心字段包含登录凭证、个人信息、状态等
shell
CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` varchar(50) NOT NULL COMMENT '用户名(唯一)',
`password` varchar(255) NOT NULL COMMENT '密码(BCrypt/SHA256加密存储)',
`nickname` varchar(50) DEFAULT '' COMMENT '用户昵称',
`email` varchar(100) DEFAULT '' COMMENT '邮箱',
`phone` varchar(20) DEFAULT '' COMMENT '手机号',
`avatar` varchar(255) DEFAULT '' COMMENT '头像URL',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
`is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`create_by` bigint DEFAULT NULL COMMENT '创建人ID',
`update_by` bigint DEFAULT NULL COMMENT '更新人ID',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`),
UNIQUE KEY `uk_phone` (`phone`) USING BTREE,
UNIQUE KEY `uk_email` (`email`) USING BTREE,
KEY `idx_status` (`status`),
KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';- 角色表
存储角色信息,角色是权限的集合(如「超级管理员」「普通用户」「运营人员」)。
shell
CREATE TABLE `sys_role` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(50) NOT NULL COMMENT '角色名称(唯一)',
`role_code` varchar(50) NOT NULL COMMENT '角色编码(唯一,如ADMIN/USER/OPERATOR)',
`description` varchar(255) DEFAULT '' COMMENT '角色描述',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
`is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
`sort` int DEFAULT 0 COMMENT '排序(用于前端展示)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_role_name` (`role_name`),
UNIQUE KEY `uk_role_code` (`role_code`),
KEY `idx_status` (`status`),
KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统角色表';- 权限表
存储最小粒度的权限(如「用户新增」「角色删除」「菜单查看」),支持层级(父权限)。
shell
CREATE TABLE `sys_permission` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '权限ID',
`perm_name` varchar(50) NOT NULL COMMENT '权限名称',
`perm_code` varchar(100) NOT NULL COMMENT '权限编码(唯一,如sys:user:add)',
`module` varchar(50) DEFAULT '' COMMENT '所属模块(如系统管理/用户管理)',
`action` varchar(20) DEFAULT '' COMMENT '操作类型(add/edit/delete/query)',
`url` varchar(255) DEFAULT '' COMMENT '关联接口/页面URL',
`parent_id` bigint DEFAULT 0 COMMENT '父权限ID(0=顶级权限)',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:0=禁用,1=启用',
`is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '软删除:0=未删,1=已删',
`sort` int DEFAULT 0 COMMENT '排序(用于前端菜单展示)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_perm_code` (`perm_code`),
KEY `idx_parent_id` (`parent_id`),
KEY `idx_status` (`status`),
KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统权限表';NestJS 中 RBAC + 菜单权限方案
RBAC(基于角色的访问控制)是企业级应用中最常用的权限模型,核心思想是用户 - 角色 - 权限的三层解耦;而菜单权限是 RBAC 的核心落地场景之一(前端动态渲染菜单、后端校验接口 / 按钮权限)
shell
用户 → 角色 → 菜单(权限),三层解耦,便于权限批量管理
1 个用户可关联多个角色,1 个角色可分配给多个用户;
1 个角色可关联多个菜单 / 权限,1 个菜单 / 权限可分配给多个角色;
用户的最终权限 = 其所有角色关联的菜单 / 权限的并集。
给用户赋予权限,不能直接给用户赋予权限,而是中间需要一个桥梁,桥梁便是角色
通过给用户分配角色,从而获得这个角色的批量权限核心概念与整体架构
- RBAC 三层模型(核心) 用户(User):系统操作者,一个用户可关联多个角色(多对多)。 角色(Role):权限的集合,比如「管理员」「普通用户」「运营」,一个角色可关联多个权限(多对多)。 权限(Permission):最小权限单元,分为两类: 「菜单 / 按钮权限」:控制前端菜单显示、按钮禁用(如 menu:user:list、button:user:add); 「接口权限」:控制后端接口访问(如 api:user:delete)。
- 整体架构
shell
用户登录 → JWT 认证 → 权限守卫(Guard)→ 解析用户角色 → 匹配权限(装饰器标记)→ 允许/拒绝访问
↓
菜单服务 → 筛选用户可访问菜单 → 返回前端渲染