TP8.0 字段级权限控制在数据组装阶段动态脱敏,通过 AclFieldService 结合用户上下文校验 resource_type 与 field_name 组合权限,支持条件表达式、缓存及 missing_permissions 响应提示。
TP8.0 实现 API 接口字段级细粒度权限控制,核心不是“拦住整个接口”,而是“放行请求但过滤响应字段”。ACL 在这里不用于路由拦截,而用于数据组装阶段的动态脱敏与裁剪。
ThinkPHP 的中间件或 AuthRule::check() 作用于请求入口,只能决定“能否进”,无法控制“出来时带哪些字段”。字段级控制必须发生在模型数据转 JSON 前——比如在资源类(Resource)、DTO 构造器、或统一响应封装层中。
不要把字段权限硬编码进模型或 Resource。应抽象出 AclFieldService,接收 user、resource_type(如 'user')、field_name(如 'salary')三参数,返回 true/false。
if (! app(AclFieldService::class)->canRead($user, 'user', 'salary')) { $data['salary'] = null; }
字段权限不是孤立存在的,它依附于具体资源实例和操作上下文。因此 resource_type 和 field_name 需配合业务语义组合使用,而非简单拼接。
user:profile:email(用户资料页的邮箱字段)、order:detail:refund_amount(订单详情中的退款金额)/api/users/123/email —— 路径含 ID,无法缓存复用;且与前端字段名耦合过紧user:profile 整体不可读,则其下所有字段默认不可读,除非显式授权字段被隐藏时,不应静默丢弃,而应在响应中提供可追溯的提示,便于前端适配或审计排查。
missing_permissions 字段,值为字符串数组,如 ["user:profile:salary"]