TP6.0 中间件中实现接口签名校验实战【防刷】

冬晨酱_5767

冬晨酱_5767

2026-07-17

859人浏览

原创

thinkphp 6.0 的 api 签名校验必须放在中间件(如 app/middleware/checksign.php)中,注册于 app/middleware.php 且位于 allowcrossdomain 之后、业务逻辑之前;需统一读取原始请求流、按字典序拼接参数并 rawurlencode 编码、校验 timestamp(≤300秒)与 redis 存储的 nonce 防重放,签名从 x-signature header 提取并用 hash_equals 安全比对。

tp6.0 中间件中实现接口签名校验实战【防刷】

在 ThinkPHP 6.0 中为 API 接口添加签名校验,是为了拦截非法请求、防止参数篡改和重放攻击,避免接口被恶意刷调用或伪造数据。这一步必须在请求进入业务逻辑前完成,否则日志已打、数据库已查、资源已消耗,验签就失去意义。

创建并注册签名校验中间件

执行命令生成中间件文件:php think make:middleware CheckSign

打开 app/middleware.php,将中间件类名加入全局中间件数组,注意必须带反斜杠且不能使用 use 语句:
【\app\middleware\CheckSign::class】 必须写在 \think\middleware\AllowCrossDomain::class 之后、业务控制器之前。

若写成 'app\middleware\CheckSign' 或漏掉开头反斜杠,中间件将完全不触发——框架加载时会尝试在当前命名空间下找类,直接报错 Class not found。

统一读取原始请求参数

签名验证失败 90% 源于参数没对齐:客户端对原始 URL 编码字符串签名,而 $request->param() 返回的是自动 urldecode() 后的结果,空格变 +、中文乱码、BOM 字符残留都会导致哈希值不一致。

第一步:调用 $request->getInput() 获取原始输入流(含 POST body 和 JSON 内容)。

第二步:根据 Content-Type 判断解析方式:
若含 application/json,用 json_decode($input, true)
否则用 parse_str($input, $body) 解析表单数据。

第三步:显式合并 GET 参数与解析后的 body:array_merge($request->get(), $parsed_body) ——否则带 query 的 POST 请求会漏掉 ?v=1.0 这类关键签名因子。

第四步:剔除签名无关字段:unset($params['sign'], $params['sign_version'], $params['app_id'])【必须先确认这些键存在再 unset,否则 PHP 警告可能干扰后续逻辑】

构造签名原文并比对

方法一:按字典序拼接参数
① 对参数数组执行 ksort($params, SORT_STRING),确保 ASCII 升序;
② 遍历拼接 key=value,用 & 连接,**每个 value 必须单独 rawurlencode()**(不是 urlencode()),避免空格转 +
③ 拼接完整路径(不含域名和 query string)+ 上述字符串 + timestamp=xxx&nonce=yyy&appid=abc
④ 最后追加密钥:$str = $path . $sorted_params_str . $secret
⑤ 计算 hash_hmac('sha256', $str, $secret) 得到期望签名。

Musico
Musico

Musico是一款可实时生成自适应音乐的 AI 作曲引擎。

下载

方法二:从 Header 提取签名值
必须用 $request->header('X-Signature') 获取,【绝不能用 $request->param('sign')$_GET['sign'] ——它们可被业务参数覆盖,存在污染风险】

比对时使用 hash_equals($expected, $provided),防时序攻击;ThinkPHP 6.0.10+ 已内置该函数,低版本需自行引入。

校验 timestamp 与 nonce

时间戳校验:
取出客户端传入的 timestamp,计算 abs($client_ts - time()),若 > 300(5 分钟),直接拒绝。
不要用 $_SERVER['REQUEST_TIME'] 替代 time(),前者是 PHP 接收请求时刻,后者是当前系统时间,偏差可能导致合法请求被拒。

Nonce 校验:
构建 Redis key:sign:nonce:{$appid}:{$nonce}
Redis::setNx($key, 1) 写入,并设 TTL 为 600 秒;
若返回 false,说明该 nonce 已被使用过,拒绝请求。

注意:Redis 连接必须提前初始化,若未配置或连接失败,需降级为本地缓存(仅限开发环境),线上必须依赖 Redis。

跳过白名单接口

在中间件 handle() 方法开头,先获取当前请求 URI:$uri = $request->server('REQUEST_URI')

定义免验签路径数组:private $whitelist = ['/api/login', '/api/register', '/captcha/get'];

in_array($uri, $this->whitelist) 判断,命中则直接 return $next($request)

不要用 ->except() 方式跳过——中间件链一旦注册就全量执行,except 是路由层功能,在全局中间件中无效。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

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

下载

相关标签:

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

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

2024.05.11

549

5

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

2025.12.18

544

18

ThinkPHP中间件机制与请求拦截处理实践
ThinkPHP中间件机制与请求拦截处理实践

本专题围绕 ThinkPHP 中间件体系展开,深入讲解中间件的定义、注册与执行流程。内容包括全局中间件与路由中间件的区别、请求前后处理逻辑、自定义中间件开发以及权限验证与日志处理应用。通过实际案例,帮助开发者掌握中间件在项目中的核心作用与最佳实践。

2026.03.31

378

17

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3028

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4189

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3649

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

366

15

Vibeknow在线使用入口合集
Vibeknow在线使用入口合集

本专题汇总了Vibeknow在线创作视频的官方入口及网页版使用教程,涵盖PPT、PDF、Word等文档一键转讲解视频的核心操作,并整理了免费版水印规则与手机端浏览器访问指南,助你快速将知识内容视频化。

2026.09.21

0

20

NumPy随机数文件读写与dtype数据类型
NumPy随机数文件读写与dtype数据类型

本专题整理 NumPy 随机数、文件读写与 dtype 数据类型相关教程,覆盖 Generator/random、随机数种子、正态分布采样、npy/npz/CSV/TXT 保存读取、loadtxt/savetxt、memmap、大文件处理、astype 类型转换、结构化 dtype、整数溢出和精度丢失等场景。

2026.09.21

0

24

热门下载

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

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习