讲师中心 微信公众号
AI工具推荐 视频效率加速

怎样在ThinkPHP中实现用户权限的细粒度控制【安全】

陌杰大大_9810

陌杰大大_9810

发布时间:2026-07-02 12:34:22

|

666人浏览过

|

来源于php中文网

原创

权限码必须落到具体接口动作,不能只靠路由节点;需定义语义化权限码(如article:delete:draft)并存入auth_rule.rule_code,校验时显式传入且大小写、符号须完全一致;API场景禁用Session,改用JWT或Redis缓存;字段级脱敏在数据组装阶段干预,数据范围过滤须显式调用scope或封装joinAuth方法;权限变更后必须强清理user_permissions_{$uid}和auth_rules_all缓存。

怎样在thinkphp中实现用户权限的细粒度控制【安全】

权限码必须落到具体接口动作,不能只靠路由节点

ThinkPHP 的 AuthRule::check() 默认只比对当前控制器/方法名(如 ArticleController/delete),但真实业务中,“删除”这个动作可能分场景:普通编辑员只能删草稿,审核员能删已发布文章,HR 只能删自己部门员工记录。光靠路由节点无法区分。

正确做法是定义带语义的权限码,例如:article:delete:draft、article:delete:published、user:delete:own_dept,并存入 auth_rule.rule_code 字段(加唯一索引)。路由层不自动映射,需在控制器方法开头显式传入:

if (!AuthRule::check('article:delete:draft', $this->userId)) {
    throw new HttpException(403);
}
  • 别依赖 $this->request->action() 拼接权限码——它返回的是 delete,不是完整上下文
  • 权限码大小写、冒号、下划线必须和数据库里 rule_code 完全一致,多一个空格就失效
  • API 场景禁用 Session,改从 JWT payload 读 permissions 数组,或查库 + Redis 缓存(key 为 user_permissions_{$uid})

字段级脱敏必须在数据组装阶段干预,不能靠中间件拦截

按钮可见、接口可调用 ≠ 数据可看全。比如财务系统中,“实发工资”字段只对 HRBP 可见,其他人应看到 **** 或 null。这类控制无法用 AuthRule::check() 解决,因为校验发生在请求入口,而字段过滤发生在数据输出前。

推荐在模型的 toArray() 或资源类(Resource)的 toArray() 中做判断:

立即学习“PHP免费学习笔记(深入)”;

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载
public function toArray($request)
{
    $data = parent::toArray($request);
    if (!AuthRule::check('salary:show:real', $this->user_id)) {
        $data['real_salary'] = '****';
    }
    return $data;
}
  • 不要在控制器里手动 unset 字段——容易漏、难复用、违反单一职责
  • 避免在数据库查询时就用 SELECT CASE WHEN ... 过滤,会导致 SQL 复杂、缓存失效、ORM 聚合失效
  • 若用 JSON 返回,字段脱敏后仍要确保序列化前已处理,否则 json_encode() 会暴露原始值

数据范围过滤必须用 scope + 显式调用,且 JOIN 时不自动下推

ThinkPHP 的 scope 不是“全局生效”,而是“按需启用”的查询预设。很多人写了 protected $scope = ['auth' => function ($query, $uid) { ... }],却在代码里直接写 UserModel::where(...)->select(),结果权限完全没起作用。

必须显式调用:

UserModel::scope('auth', $this->userId)->where('status', 1)->select();
  • 闭包 scope 才能传参;静态方法 scopeAuth() 拿不到登录用户,硬编码会越权或拦截失效
  • withScope() 是替换而非叠加,withScope(['auth']) 会清掉默认 scope,慎用
  • JOIN 查询中,scope 只作用于主表,子表(如 order、product)需手动补条件:->join('order o', 'u.id = o.user_id AND o.status IN (0,1)')
  • 更安全的做法是封装 joinAuth() 方法,在里面统一处理各表的可见性逻辑

权限变更后缓存必须强清理,尤其注意 Swoole 场景

用户刚被分配新权限,前端按钮仍灰、接口仍 403,90% 是缓存没清干净。Redis 缓存 key 要覆盖两个维度:user_permissions_{$uid} 和 auth_rules_all(用于权限码全量映射)。

所有后台权限变更操作(增删角色权限、用户换角色)都必须同步执行:

cache('user_permissions_' . $userId, null);
cache('auth_rules_all', null);
  • 别用 static $cache = [] 做本地内存缓存——Swoole/Workerman 下进程不共享,部分请求永远读到旧权限
  • TP6.0+ 的 think-auth 扩展默认不监听权限变更事件,得自己在管理后台的权限保存逻辑里加清理代码
  • 调试时可在 checkPermission() 开头加日志,输出实际查的缓存 key 和返回值,比猜快得多

细粒度控制最易被忽略的点是:权限码定义、数据过滤时机、缓存生命周期这三者必须严格对齐。差一环,要么放行越权,要么误拦合法请求。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

10964

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

6381

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2155

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

4028

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

4754

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

3731

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

5337

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

4182

2023.11.13

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

60

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn