PHP实现一个简单的接口签名方法以及思路分析

文章目录

  • 签名生成说明
  • 签名生成示例代码
  • 签名校验示例代码

签名生成说明

B项目需要调用A项目的接口,由A项目为B项目分配 AccessKeySecretKey,用于接口加密,确保不易被穷举,生成算法不易被猜测。

最终需要确保包含签名的参数只能被有效的请求一次,重复请求则视为无效参数;并且设定参数有效时长(例如5分钟),超时则视为无效参数。

AccessKey 和 SecretKey分配:

测试环境:
ACCESS_KEY = test_access
SECRET_KEY = test_secret正式环境:(另行配置)

假设A项目和B项目通过json格式传递参数,在PHP中对请求的json参数转化为数组,然后对原本的请求参数追加如下字段值:

  • AccessKey:已分配的请求key,固定值;
  • timestamp:当前毫秒时间戳;
  • nonce:唯一随机10位字符串,15分钟内不允许重复;

例如,原本的请求参数 $params 为:

Array
([ToUserName] => wxdd5624bd15b1691a[FromUserName] => sys[CreateTime] => 1717554600[MsgType] => event[Event] => sys_approval_change[AgentID] => 1000043
)

$params 追加 AccessKeytimestampnonce 之后:

Array
([ToUserName] => wxdd5624bd15b1691a[FromUserName] => sys[CreateTime] => 1717554600[MsgType] => event[Event] => sys_approval_change[AgentID] => 1000043[AccessKey] => test_access[timestamp] => 1717659814771[nonce] => 6bc6f34969
)

$params 的 key 值按照字母升序排列(PHP中的 ksort 函数):

Array
([AccessKey] => test_access[AgentID] => 1000043[CreateTime] => 1717554600[Event] => sys_approval_change[FromUserName] => sys[MsgType] => event[ToUserName] => wxdd5624bd15b1691a[nonce] => 756c577626[timestamp] => 1717659831355
)

然后,将上述参数赋给一个临时的变量(例如:$tmp_params),并且拼接 SecretKey,然后整体json_encode,再次md5之后,得到sign值,代码如下:

$sign = md5(json_encode($tmp_params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));

sign值 追加到 $params 参数中(注意:是$params参数,不是 $tmp_params ),最终参数如下:

Array
([AccessKey] => test_access[AgentID] => 1000043[CreateTime] => 1717554600[Event] => sys_approval_change[FromUserName] => sys[MsgType] => event[ToUserName] => wxdd5624bd15b1691a[nonce] => 137c128684[timestamp] => 1717660145228[sign] => ff0ea47d561eb2d9735771f0bc85ad33
)

将上述参数转化为json后作为最终的请求参数:

{"AccessKey": "test_access","AgentID": "1000043","CreateTime": "1717554600","Event": "sys_approval_change","FromUserName": "sys","MsgType": "event","ToUserName": "wxdd5624bd15b1691a","nonce": "fb212b7327","timestamp": 1717660335729,"sign": "9e5321b10ddc975b89a228e94d8e5f04"
}

签名生成示例代码

public function createSign()
{$mock_json = '{"ToUserName": "wxdd5624bd15b1691a","FromUserName": "sys","CreateTime": "1717554600","MsgType": "event","Event": "sys_approval_change","AgentID": "1000043"}';$params = json_decode($mock_json, true);//对原本的请求参数追加如下字段值:$params['AccessKey'] = 'test_access'; //已分配的请求key,固定值$params['timestamp'] = intval(microtime(true) * 1000); //当前毫秒时间戳$params['nonce'] = substr(uniqid(), -6) . rand(1000, 9999); //唯一随机10位字符串,15分钟内不允许重复//按照上述所有请求参数的key值的字母升序排列(PHP中的 `ksort` 函数):ksort($params);//然后,将上述参数赋给一个临时的变量,并且拼接 SecretKey, 然后整体json_encode,再次md5之后,得到sign值$tmp_params = $params;$tmp_params['SecretKey'] = 'test_secret';$sign = md5(json_encode($tmp_params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));//将 sign值 追加到 $params 参数中(注意:是$params参数,不是 $tmp_params )$params['sign'] = $sign;//将上述参数转化为json后作为最终的请求参数:echo json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}

签名校验示例代码

<?phpclass Demo
{//时间常量const TIME_OUT = 300; //超时时间  5分钟const NONCE_INTERVAL = 900;   //允许nonce时间间隔   15分钟/*** 签名验证* @param $params array 客户端请求来的原本的参数数组* @return array* @throws \Exception*/public function checkSign($params){$request_params = $params;if (empty($params['timestamp']) || empty($params['nonce']) || empty($params['sign'])) {throw new \Exception('签名基础参数校验失败', 201);}//校验超时$timestamp = intval($params['timestamp'] / 1000);if (abs(time() - $timestamp) > self::TIME_OUT) {throw new \Exception('请求参数已超时', 201);}//从配置文件中读取ACCESS_KEY和SECRET_KEY$access_key = env('ACCESS_KEY');$secret_key = env('SECRET_KEY');if (empty($access_key) || empty($secret_key)) {throw new \Exception('NEW_CRM_REQUEST配置异常', 201);}if ($access_key != $params['AccessKey']) {throw new \Exception('无效的AccessKey', 201);}$nonce_key = 'test_nonce:' . $params['timestamp'] . '_' . $params['nonce'];$exist_nonce = RedisUtils::init()->get($nonce_key);if ($exist_nonce) {throw new \Exception('无效的nonce值', 201);}$sign = $params['sign'];unset($params['sign']);ksort($params);$params['SecretKey'] = $secret_key;$params_json = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);$params_sign = md5($params_json);if ($params_sign != $sign) {//todo 写入错误log 或 发送报警信息//todo 校验频繁请求失败的IP,可以考虑将这些IP加入黑名单throw new \Exception('签名校验失败', 201);}RedisUtils::init()->set($nonce_key, 1, self::NONCE_INTERVAL);unset($params['AccessKey']);unset($params['SecretKey']);unset($params['nonce']);unset($params['timestamp']);return $params;}
}

最终效果,同样的请求参数如果被抓包,再次请求就会失败:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/851225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

32-读取Excel数据(xlrd)

本篇介绍如何使在python中读取excel数据。 一、环境准备 先安装xlrd模块&#xff0c;打开cmd&#xff0c;输入 pip install xlrd 在线安装。 二、基本操作 import xlrd# 打开excel表格 data xlrd.open_workbook(test.xlsx)# 2.获取sheet表格 # 方式一&#xff1a;通过索引顺…

RocketMq详解:二、SpringBoot集成RocketMq

在上一章中我们对Rocket的基础知识、特性以及四大核心组件进行了详细的介绍&#xff0c;本章带着大家一起去在项目中具体的进行应用&#xff0c;并设计将其作为一个工具包只提供消息的分发服务和业务模块进行解耦 在进行本章的学习之前&#xff0c;需要确保你的可以正常启动和…

MySQL中的数据库约束

目录 导读&#xff1a; 约束类型 1、not null&#xff08;不能为空&#xff09; 2、unique(唯一) 3、default(默认值约束) 4、primary key(唯一)与unique 相同点&#xff1a; 不同点&#xff1a; auto_increment&#xff1a; 5、foreign key(外键) 语法形式&#xff…

康姿百德集团公司官网床垫价格透明,品质睡眠触手可及

选择康姿百德床垫&#xff0c;价格透明品质靠谱&#xff0c;让你拥有美梦连连 在当今社会&#xff0c;良好的睡眠质量被越来越多的人所重视。睡眠不仅关系到我们第二天的精力状态&#xff0c;更长远地影响着我们的身体健康。因此&#xff0c;选择一款合适的床垫对于获得优质睡…

antdv 穿梭框

antd的穿梭框的数据貌似只接收key和title&#xff0c;而且必须是字符串&#xff08;我测试不是字符串的不行&#xff09;&#xff0c; 所以要把后端返回的数据再处理一下得到我们想要的数据 除了实现简单的穿梭框功能&#xff0c;还想要重写搜索事件&#xff0c;想达到的效果是…

FastAPI:在大模型中使用fastapi对外提供接口

通过本文你可以了解到&#xff1a; 如何安装fastapi&#xff0c;快速接入如何让大模型对外提供API接口 往期文章回顾&#xff1a; 1.大模型学习资料整理&#xff1a;大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业RAG系统&#xff0c;如何评估…

解决!word转pdf时,怎样保持图片不失真

#今天用word写了期末设计报告&#xff0c;里面有很多过程的截图&#xff0c;要打印出来&#xff0c;想到pdf图片不会错位&#xff0c;就转成了pdf&#xff0c;发现图片都成高糊了&#xff0c;找了好多方法&#xff0c;再不下载其他软件和插件的情况下&#xff0c;导出拥有清晰的…

BarTender 常见的使用要点

BarTender 简述 BarTender是由美国海鸥科技&#xff08;Seagull Scientific&#xff09;推出的一款条码打印软件&#xff0c;被广泛应用于标签、条形码、证卡和RFID标记的设计和打印领域。它在全球范围内拥有众多用户&#xff0c;被公认为标签打印方面的全球领先者。BarTender…

JavaScript基础用法(变量定义、输入输出、转义符、注释和编码规范)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

史上最详细四叉树地图不同技术应用和代码详解

四叉树地图在计算机和机器人领域应用的很广&#xff0c;但是初学者可能会发现四叉树地图有各种不同的实现方式&#xff0c;很多在机器人领域不适用或是在计算机存储领域不适用。今天我就讲解下各类四叉树的实现方式和应用场景。 史上最详细四叉树地图不同技术应用和代码详解 本…

Bio-Info每日一题:Rosalind-06-Counting Point Mutations

&#x1f389; 进入生物信息学的世界&#xff0c;与Rosalind一起探索吧&#xff01;&#x1f9ec; Rosalind是一个在线平台&#xff0c;专为学习和实践生物信息学而设计。该平台提供了一系列循序渐进的编程挑战&#xff0c;帮助用户从基础到高级掌握生物信息学知识。无论你是初…

Navicat导入json文件(json文件数据导入到MySQL表中)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

多目标融合参数搜索

多目标融合 权重分类目人群。 trick normlize 不同Score之间含义、量级和分布差异较大&#xff1a;评分计算的不同部分的意义、范围和分布存在显著差异&#xff0c;这使得直接比较或融合它们的结果变得困难。显式反馈&#xff08;如点赞率&#xff09;存在用户间差异&#…

【9】openssl 代码调试

0x01 前言 最近在学习密码学&#xff0c;但是国密算法(SM2&#xff0c;SM3,SM4,SM9)的细节都在openssl项目里&#xff0c;当然一些国际算法也在。想着看下代码执行过程和理论结合起来。中间走了一些弯路&#xff0c;做个笔记。 0x02 openssl安装 一开始认为是不是直接下载好的…

Layui实现下拉多选功能

1、问题概述? 提供源码下载 在项目中有很多地方需要使用到下拉框,并且实现选择多个信息,下面是展示。 支持如下功能: 1、分页 2、主题自定义 3、国际化 4、下拉方向 5、Tips修改等 6、Style自定义样式 7、取值 8、赋值 2、资源准备及测试? 2.1、资源下载

Leetcode 力扣113. 路径总和 II (抖音号:708231408)

给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22 输出&a…

中山大学和字节发布「视频虚拟试穿」扩散模型VITON-DiT,一键生成换装后视频!

视频虚拟试穿技术日益受到关注&#xff0c;然而现有的工作局限于将服装图像转移到姿势和背景简单的视频上&#xff0c;对于随意拍摄的视频则效果不佳。最近&#xff0c;Sora 揭示了 Diffusion Transformer (DiT) 在生成具有真实场景的逼真视频方面的可扩展性&#xff0c;可以说…

Kubernetes入门-大简介

目录 何为微服务 何为云原生 何为编排器 “Kubernetes”这个名字来自希腊语&#xff0c;意思是“舵手”舵手是一个航海/航行术语&#xff0c;指掌舵的人从本质上说&#xff0c;Kubernetes是云原生微服务(cloud-native microservice)应用的编排器(orchestrator) 何为微服务 …

WordPress 高级缓存插件 W3 Total Cache 开启支持 Brotli 压缩算法

今天明月给大家分享一下 WordPress 高级缓存插件 W3 Total Cache 开启支持 Brotli 压缩算法的教程&#xff0c;在撰写【WordPress 高级缓存插件 W3 Total Cache Pro 详细配置教程】一文的时候明月就发现 W3 Total Cache 已经支持 Brotli 压缩算法了&#xff0c;可惜的是在安装完…

ctfshow-web入门-命令执行(web53-web55)

目录 1、web53 2、web54 3、web55 1、web53 这里的代码有点不一样&#xff0c;说一下这两种的区别&#xff1a; &#xff08;1&#xff09;直接执行 system($c); system($c);这种方式会直接执行命令 $c 并将命令的输出直接发送到标准输出&#xff08;通常是浏览器&#xff…