数据权限
数据权限是一种行级安全控制机制,用于限制用户只能访问其权限范围内的数据行。与功能权限(控制用户能执行哪些操作)不同,数据权限控制用户能看到哪些数据。
设计目标
| 目标 | 说明 |
|---|---|
| 细粒度控制 | 按组织架构维度控制数据可见范围 |
| 多角色支持 | 用户拥有多个角色时,采用并集策略合并权限 |
| 无侵入实现 | 封装 DataPermissionService,业务代码简洁 |
| 灵活配置 | 支持全部、部门层级、个人、自定义等多种范围 |
数据范围类型
| 值 | 类型 | 说明 |
|---|---|---|
1 | 全部数据 | 可访问系统所有数据 |
2 | 本部门及子部门 | 可访问用户所属部门及其下级部门的数据 |
3 | 本部门 | 仅可访问用户所属部门的数据 |
4 | 本人 | 仅可访问自己创建的数据 |
5 | 自定义 | 可访问指定部门的数据(需配置部门列表) |
核心组件
服务定义
php
class DataPermissionService
{
public function apply(object $query, string $deptIdColumn, string $userIdColumn, array $authUser): object;
}核心逻辑:
- ROOT 用户跳过过滤
- 无数据权限配置默认只能查看本人数据
- 任一角色为 ALL 范围则跳过过滤
- 多角色采用并集策略合并
多角色权限合并策略
用户拥有多个角色时采用并集(OR)策略:
- ALL优先:任一角色拥有"全部数据"权限时跳过所有过滤
- OR连接:各角色的过滤条件通过
OR连接取并集 - 示例:角色A(本部门) + 角色B(自定义部门) →
WHERE (dept_id = 10 OR dept_id IN (20, 30))
自定义部门权限
数据库设计:sys_role.data_scope 字段 + sys_role_dept 关联表
登录时构建 dataScopes 写入 JWT,格式:
json
[{ "roleCode": "ADMIN", "dataScope": 5, "customDeptIds": [10, 20] }]JWT Token 存储
dataScopes 存储在 JWT Token 中,中间件解析后注入 $request。
使用指南
php
$q = Db::name('sys_user')->alias('u');
$dataPermissionService->apply($q, 'u.dept_id', 'u.id', $authUser);过滤条件说明
| 数据范围 | 过滤逻辑 |
|---|---|
All | 不添加过滤条件 |
DeptAndSub | 基于 sys_dept.tree_path 使用 FIND_IN_SET 匹配 |
Dept | deptId = currentUser.deptId |
Self | userId = currentUser.userId |
Custom | deptId IN (customDeptIds) |
相关文件
| 文件路径 | 说明 |
|---|---|
app/common/enums/DataScopeEnum.php | 数据权限枚举定义 |
app/system/service/DataPermissionService.php | 核心处理器 |
app/common/middleware/DataScopeMiddleware.php | 数据范围中间件 |
extend/jwt/JwtClaimConstants.php | JWT 声明常量 |
extend/jwt/JwtTokenManager.php | JWT 生成与解析 |
app/system/service/UserService.php | 用户服务(应用权限过滤) |
app/system/service/DeptService.php | 部门服务(应用权限过滤) |
app/system/service/NoticeService.php | 通知服务(应用权限过滤) |
