feat: 初始化进销存数据开放平台项目
初始化完整的前后端项目结构,包含ThinkPHP后端API服务和Next.js前端管理系统,添加基础配置、中间件、模型、路由等核心代码,以及项目文档和静态资源。
This commit is contained in:
107
thinkphp/app/service/Signature.php
Normal file
107
thinkphp/app/service/Signature.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace app\service;
|
||||
|
||||
/**
|
||||
* 签名验证服务
|
||||
* 完全按照 Python 版本实现
|
||||
*/
|
||||
class Signature
|
||||
{
|
||||
/**
|
||||
* 生成API Key
|
||||
*/
|
||||
public static function generateApiKey()
|
||||
{
|
||||
return bin2hex(random_bytes(6));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成API Secret
|
||||
*/
|
||||
public static function generateApiSecret()
|
||||
{
|
||||
return bin2hex(random_bytes(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对 API Secret 做 SHA256 哈希存储
|
||||
*/
|
||||
public static function hashSecret($secret)
|
||||
{
|
||||
return hash('sha256', $secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证签名(完全按照 Python 版本实现)
|
||||
*
|
||||
* @param array $params 请求查询参数
|
||||
* @param string $timestamp X-Timestamp header 值
|
||||
* @param string $signature X-Sign header 值
|
||||
* @param string $apiSecretHash 数据库存储的 secret 哈希
|
||||
* @return bool
|
||||
*/
|
||||
public static function verify($params, $timestamp, $signature, $apiSecretHash)
|
||||
{
|
||||
try {
|
||||
$ts = (int)$timestamp;
|
||||
if ($ts > 1e12) {
|
||||
$ts = (int)($ts / 1000);
|
||||
}
|
||||
$now = time();
|
||||
$expireSeconds = env('signature.expire_seconds', 300);
|
||||
if (abs($now - $ts) > $expireSeconds) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sortedParams = [];
|
||||
foreach ($params as $k => $v) {
|
||||
$sortedParams[$k] = $v;
|
||||
}
|
||||
ksort($sortedParams);
|
||||
|
||||
$paramParts = [];
|
||||
foreach ($sortedParams as $k => $v) {
|
||||
if ($v !== null && $v !== '') {
|
||||
$paramParts[] = "{$k}={$v}";
|
||||
}
|
||||
}
|
||||
$paramStr = implode('&', $paramParts);
|
||||
$fullStr = $paramStr . '×tamp=' . $timestamp;
|
||||
|
||||
$expectedSign = hash_hmac('sha256', $fullStr, $apiSecretHash);
|
||||
|
||||
return strcasecmp($expectedSign, $signature) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名(用于测试)
|
||||
*
|
||||
* @param array $params 请求参数
|
||||
* @param string $timestamp 时间戳字符串
|
||||
* @param string $apiSecret API Secret 明文
|
||||
* @return string
|
||||
*/
|
||||
public static function sign($params, $timestamp, $apiSecret)
|
||||
{
|
||||
$sortedParams = [];
|
||||
foreach ($params as $k => $v) {
|
||||
$sortedParams[$k] = $v;
|
||||
}
|
||||
ksort($sortedParams);
|
||||
|
||||
$paramParts = [];
|
||||
foreach ($sortedParams as $k => $v) {
|
||||
if ($v !== null && $v !== '') {
|
||||
$paramParts[] = "{$k}={$v}";
|
||||
}
|
||||
}
|
||||
$paramStr = implode('&', $paramParts);
|
||||
$fullStr = $paramStr . '×tamp=' . $timestamp;
|
||||
|
||||
return hash_hmac('sha256', $fullStr, $apiSecret);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user