设计用户、角色、权限、资源四者关系的数据模型,通过关联表实现多对多关系;2. 将权限按资源和操作粒度分配给角色,如admin拥有所有权限,editor可创建和编辑文章;3. 用户登录后查询其角色对应的权限列表,并缓存至session或jwt中供后续使用;4. 在接口或页面通过中间件或前端逻辑校验用户是否具备所需权限;5. 可选支持角色继承,通过parent_role_id字段实现层级关系;6. 提供管理后台实现角色、权限、用户的动态配置与分配;需注意权限粒度适中、避免直接赋权给用户,并及时更新权限缓存,确保用户→角色→权限→资源的控制链路清晰可维护。

实现基于角色的访问控制(RBAC)的核心是将权限分配给角色,再将角色分配给用户,从而间接控制用户能访问哪些资源。这种方式比直接给用户赋权更灵活、易维护,尤其适合中大型系统。以下是实现RBAC的关键步骤和设计思路。
1. 设计核心数据模型
RBAC 的基础是四个核心实体:用户(User)、角色(Role)、权限(Permission)、资源(Resource)。它们之间的关系如下:
- 用户 拥有 角色
- 角色 拥有 权限
- 权限 对应对某个 资源 的操作(如:读、写、删除)
数据表设计示例(关系型数据库):
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50) UNIQUE
);
-- 角色表
CREATE TABLE roles (
id INT PRIMARY KEY,
name VARCHAR(50) UNIQUE, -- 如:admin, editor, viewer
description TEXT
);
-- 权限表
CREATE TABLE permissions (
id INT PRIMARY KEY,
resource VARCHAR(50), -- 如:article, user, order
action VARCHAR(20) -- 如:read, create, update, delete
);
-- 角色与权限的关联表(多对多)
CREATE TABLE role_permissions (
role_id INT,
permission_id INT,
PRIMARY KEY (role_id, permission_id)
);
-- 用户与角色的关联表(多对多)
CREATE TABLE user_roles (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id)
);2. 分配权限给角色
在系统初始化或管理后台中,预先定义好角色所需的权限。例如:
- admin 角色:拥有所有资源的所有操作权限
- editor 角色:可以创建和编辑文章(article:create, article:update)
- viewer 角色:只能读取文章(article:read)
这些配置可以通过后台界面或配置文件完成。
3. 用户登录后获取权限
用户登录成功后,系统需要根据其角色,查询出所有关联的权限,通常缓存到会话(Session)或 Token(如 JWT)中。
权限获取流程:
- 查询用户的所有角色(通过
user_roles
表) - 根据角色查询所有权限(通过
role_permissions
和permissions
表) - 将权限列表存储在用户上下文中(如内存、Redis、JWT payload)
例如在 JWT 中可以这样存:
{
"user_id": 123,
"roles": ["editor"],
"permissions": ["article:create", "article:update", "article:read"]
}4. 在接口或页面中进行权限校验
每次请求敏感资源时,检查当前用户是否拥有对应权限。
校验方式举例:
- 后端中间件/拦截器:在 API 路由前进行权限判断
# 伪代码示例(Flask 风格)
def require_permission(permission):
def decorator(func):
def wrapper(*args, **kwargs):
user_permissions = get_current_user_permissions()
if permission not in user_permissions:
return "Forbidden", 403
return func(*args, **kwargs)
return wrapper
return decorator
@require_permission("article:create")
def create_article():
# 创建文章逻辑
pass- 前端控制:根据权限隐藏或禁用按钮
// 用户有 article:create 权限才显示“新建文章”按钮
{ hasPermission('article:create') && }5. 支持角色继承和层级(可选高级功能)
有些系统需要角色之间有继承关系,比如:
admin
继承editor
的所有权限editor
继承viewer
的权限
实现方式可以引入“角色父级”字段:
ALTER TABLE roles ADD COLUMN parent_role_id INT;
或者使用权限组、角色组等抽象方式管理。
6. 管理后台与动态配置
为了便于运维,建议提供一个管理界面,支持:
- 创建/编辑/删除角色
- 为角色分配权限
- 为用户分配角色
- 查看权限继承关系
这样非开发人员也能调整权限策略,而无需改代码。
小贴士:避免常见问题
- 权限粒度要合理:太粗(如“管理员能干一切”)不安全,太细(每个按钮一个权限)难维护。建议按资源+操作建模。
- 避免直接给用户赋权限:RBAC 的核心是“通过角色中转”,否则就退化为直接授权。
- 权限缓存要更新及时:当角色权限变更时,相关用户的权限缓存需刷新。
基本上就这些。RBAC 不复杂,但设计好模型和流程能极大提升系统的安全性和可维护性。关键在于:用户 → 角色 → 权限 → 资源操作 这条链路要清晰、可查、可配。










