1. 需求分析
在在线考试系统的设计中,用户权限管理是确保系统安全与可控性的核心模块。通过RBAC模型,可以将权限从具体用户解耦出来,使得权限管理更加高效、可扩展。
系统的目标用户包括考生、教师、管理员和考试组委会等,不同角色需要覆盖的操作集合不同,如创建题库、发布考试、阅卷、查看成绩、管理用户等。需求多面性要求权限模型既要细粒度又要易于维护。
核心场景与约束
应遵循最小权限原则,避免默认授权过多操作;同时支持直接授权给个人的权限以及通过角色授权的组合权限。
还需要实现审计留痕,记录谁在何时对哪些资源进行了何种权限变更或访问,以满足合规性要求。
2. 设计原则
核心设计原则
采用<RBAC作为核心授权模型,角色承担权限集合,用户通过一个或多个角色获得相应权限,降低直接权限管理的复杂度。
遵循可扩展性,让新增的考试场景、题型和资源类型能够通过扩展角色与权限来实现,而不破坏现有数据结构。
审计与可追溯性
对权限变更和关键操作进行审计日志记录,字段包括操作人、动作、目标对象以及时间戳,便于事后追踪与合规审计。
3. 数据库表结构总览
核心实体与关系
核心实体包括<用户(users)、角色(roles)、权限(permissions),以及它们之间的映射表:用户-角色映射(user_roles)、角色-权限映射(role_permissions),另设直接权限表(user_permissions)以支持对个别用户的特例授权,同时通过审计日志(audit_log)实现操作溯源。
为了保证数据一致性,表之间通过外键进行约束,且对映射表设置复合主键以确保多对多关系的唯一性与完整性。
关系与查询要点
在实际查询中,通常需要聚合“直接权限”与“角色权限”的并集,形成某个用户的“有效权限集合”,这需要编写<高效的联合查询与去重逻辑。
4. 具体表结构设计
4.1 用户表设计
用户表用于存储系统中所有注册用户的基本信息,字段设计应支持唯一标识、认证信息、状态以及时间信息,便于认证与统计分析。唯一标识通常使用自增主键或全局唯一标识符(UUID),密码字段应采用散列存储并尽量附带盐值。
CREATE TABLE users (
id BIGINT NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
email VARCHAR(100),
status ENUM('active','inactive','suspended') DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
在此基础上,可以为用户名添加唯一索引以提升查找效率,并对敏感信息进行适当的脱敏处理。索引设计应覆盖经常查询的字段,如 username、email、status。
4.2 角色表设计
角色表定义系统中的权限集合分组,便于将复杂权限组合化并重复使用。角色名称应具描述性,描述字段用于对角色用途进行说明。
CREATE TABLE roles (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
description TEXT,
PRIMARY KEY (id)
);
通过角色名称,可以实现对权限集合的直观管理,后续可通过角色的描述字段帮助运维理解权限分配的意图。角色表应支持软删除或历史版本以便追踪角色演变。
4.3 权限表设计
权限表用于描述系统中可授予的具体操作粒度,如“创建题目”、“发布考试”、“阅卷”等。权限名称应具可读性,描述字段用于提供更详细的权限含义。
CREATE TABLE permissions (
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
PRIMARY KEY (id)
);
权限应具备唯一性,避免重复定义;在应用层实现时,可将权限名称映射到具体业务操作的接口或按钮,以实现前后端的一致性控制。权限的增删改需审计记录,以确保改动可追溯。
4.4 映射表设计
映射表实现多对多关系:角色-权限以及用户-角色。通过这两张表可以灵活组合权限,确保权限的可复用性与可维护性。
-- 用户与角色的多对多映射
CREATE TABLE user_roles (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
);
-- 角色与权限的多对多映射
CREATE TABLE role_permissions (
role_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
另外,为了支持对单个用户的直接授权,可以添加下述直接权限映射表。直接权限有助于处理临时或例外情况,但应通过审计记录进行监控。
-- 用户直接拥有的权限
CREATE TABLE user_permissions (
user_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
granted_by BIGINT,
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, permission_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
4.5 审计日志设计
审计日志用于记录权限变更、重要操作的轨迹,字段设计应覆盖<操作者、动作、目标对象、时间戳等信息。
CREATE TABLE audit_log (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id BIGINT,
action VARCHAR(255),
target VARCHAR(255),
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
结合应用层日志,审计日志可以实现对权限演变的全生命周期追踪,帮助发现异常权限变更行为。定期归档与索引优化有利于查询性能与存储管理。
5. 实现与查询示例
5.1 获取用户的全部权限
要获取某个用户的完整权限集合,需要聚合“直接权限”和“角色权限”的并集,并进行去重。查询要高效、幂等,并能兼容权限的动态变更。
SELECT DISTINCT p.name AS permission
FROM users u
LEFT JOIN user_permissions up ON up.user_id = u.id
LEFT JOIN permissions p ON p.id = up.permission_id
WHERE u.id = ?
UNION
SELECT DISTINCT p.name AS permission
FROM users u
JOIN user_roles ur ON ur.user_id = u.id
JOIN role_permissions rp ON rp.role_id = ur.role_id
JOIN permissions p ON p.id = rp.permission_id
WHERE u.id = ?;
上述查询通过UNION 去重实现了两类来源权限的聚合,适用于读取时计算“有效权限集合”。
5.2 审计日志与变更记录示例
当管理员授予或撤销权限时,应记录到审计日志,以便后续分析和合规检查。示例操作包含权限变更、角色分配、直接权限的增删等。
INSERT INTO audit_log (user_id, action, target)
VALUES (123, 'GRANT_PERMISSION', 'role:teacher|permission:publish_exam');
将操作人、动作、目标对象、时间戳组合存储,有助于追踪权限的历史演变。
6. 运营与维护要点
6.1 数据一致性与备份
确保<事务性写入涵盖用户、角色、权限及映射表的变更,以防止不一致状态的产生。
建立定期全量与增量备份策略,以及必要的异地备份,确保在灾难发生时能够快速恢复授权状态。
6.2 安全与合规
密码采用强散列算法并附带盐值,且定期轮换。访问控制应通过最小权限原则实施,所有敏感操作应触发审计日志记录。
对于多环境部署,应区分开发、测试、预发布与生产环境的权限范围,避免跨环境权限影响安全。


