ThinkPHP 5.1 防止 API 接口参数篡改的签名算法【防刷】
PhpStorm 是 JetBrains 推出的专业 PHP 集成开发环境,可在 Mac 上完成代码编写、智能检查、重构、调试、测试和数据库管理。它支持主流 PHP 框架、Composer、Git、Docker 与远程解释器。
API参数防篡改签名算法需在中间件中验证,先获取原始参数并归一化,剔除签名相关字段后排序拼接,加入timestamp、nonce和密钥构成签名原文,用HMAC-SHA256计算并base64编码,比对时防时序攻击,校验timestamp超时和nonce重复使用。
先抛一个问题:API 参数被篡改,最常见的原因是什么?很多人第一反应是“没加签名”。但真实情况往往更扎心——签名算法本身就有漏洞。比如,漏掉了timestamp校验,nonce没去重,甚至在拼接字符串时用了urlencode而不是rawurlencode,结果服务端和客户端算出来的HMAC-SHA256值永远对不上。
开篇之前,先说一个咱们都懂的常识:签名验证这件事,一定要放在中间件里做。
签名验证必须放在中间件里
新建中间件很简单:执行 php think make:middleware CheckApiSign,然后在 app/middleware.php 中注册它。关键是要保证这个中间件排在路由解析之后、业务控制器之前。
在中间件的 handle 方法里,上来就提取签名。如果校验失败,直接返回 json(['code'=>401,'msg'=>'sign invalid']) 并终止流程。千万别放行到控制器里面。
【关键】控制器里写验签,等于把锁装在屋里——恶意参数已经触发了日志写入、库存扣减甚至数据库事务,验签就完全失去了意义。
统一获取原始参数并归一化
第一步:调用 $raw = $request->getInput() 一次性读取 php://input 流。如果为空,可以 fallback 到 file_get_contents('php://input')。
第二步:根据 $request->header('content-type') 进行分支处理:
如果包含 application/json,就用 json_decode($raw, true);
否则,用 parse_str($raw, $body)。
第三步:合并参数:$params = array_merge($request->get(), $body ?: []);。然后对每个值执行 trim(str_replace(["\r","\n"], '', (string)$v)),把隐藏字符清除干净。
第四步:剔除非业务字段。注意顺序:先 isset() 判断是否存在,避免 Notice 报错,再 unset($params['sign'], $params['signature'], $params['timestamp'], $params['nonce']);。
构造签名原文的三要素
方法一:基础拼接(适用于 GET 或简单表单)。
对 $params 执行 ksort($params, SORT_STRING);
然后遍历拼接 rawurlencode($k).'='.rawurlencode($v),用 & 连接;
再追加 ×tamp=xxx&nonce=yyy(注意:timestamp 必须是客户端传入的 Unix 秒级时间戳);
最后拼上密钥:$data = $query_string . '×tamp=' . $ts . '&nonce=' . $nonce . '&key=' . config('api.sign_key');。
方法二:带上 HTTP 方法和路径(可以防止接口被挪用)。
取 $method = strtoupper($request->method()); 和 $uri = parse_url($request->url(), PHP_URL_PATH);;
签名原文格式为:$method . "\n" . $uri . "\n" . $query_string . "\n";
【关键】换行符必须是 \n,不能是 \r\n,否则哈希值会错位。
计算与比对签名
计算签名:用 hash_hmac('sha256', $data_string, config('api.sign_key'), true) 计算二进制签名,再 base64_encode() 编码为字符串。
从 Header 中取签名:$clientSign = $request->header('X-Signature');。千万不要用 $request->param('sign'),后者可能会被业务参数污染。
比对时,用 hash_equals($serverSign, $clientSign) 来防止时序攻击。如果 ThinkPHP 5.1 没有这个函数,在低风险场景下可以用 ==。
校验 timestamp:abs(time() - $ts) > 300,超时直接拒绝。nonce 存 Redis:Redis::setex('nonce:' . $nonce, 600, 1),如果已存在,则验签失败。
WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,
Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。
REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。
Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理工具,可在 Windows 上完成照片修饰、选区抠图、图层合成、文字排版、绘画及生成式编辑。软件采用订阅授权,由 Creative Cloud 管理安装、更新与许
Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator
Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。













