提交代码

This commit is contained in:
youda 2025-04-12 18:35:05 +08:00
parent 3eec765f4c
commit 58fdb35f3c
5 changed files with 81 additions and 17 deletions

View File

@ -27,12 +27,12 @@ class Allow
if (strtoupper($request->method()) == "OPTIONS") {
exit;
}
// 对GET请求进行签名验证
if (strtoupper($request->method()) == "GET") {
$this->verifySignature($request);
}
// 处理跨域
// 后置中间件
$response = $next($request);
@ -48,55 +48,67 @@ class Allow
{
// 获取所有GET参数
$params = $request->get();
// 获取当前请求路径
$path = $request->pathinfo();
// 白名单路径检查 - 不需要验证域名的路径
$whitelistPaths = $this->getWhitelistPaths();
foreach ($whitelistPaths as $whitePath) {
// 支持简单的路径匹配,如 'notify/*' 匹配所有通知路径
if ($this->pathMatch($whitePath, $path)) {
// 白名单路径,跳过域名检查
// \think\facade\Log::info('白名单路径访问: ' . $path . ', 域名: ' . $);
return;
}
}
// 如果请求中携带is_test=true参数则跳过签名验证
if (isset($params['is_test']) && $params['is_test'] === 'true') {
return;
}
// 检查是否有必要的签名参数
if (!isset($params['timestamp']) || !isset($params['sign'])) {
$this->error('缺少必要的签名参数');
}
// 检查请求时间戳是否在合理范围内例如5分钟内
if (time() - intval($params['timestamp']) > 300) {
$this->error('请求已过期');
}
// 从请求中获取签名
$requestSign = $params['sign'];
//移除url
unset($params['s']);
// 从参数中移除签名,用于生成本地签名
unset($params['sign']);
// 按照键名对参数进行排序
ksort($params);
// 组合参数为字符串
$signStr = '';
foreach ($params as $key => $value) {
$signStr .= $key . '=' . $value . '&';
}
// 获取当前请求的域名和时间戳,组合为密钥
$host = $request->host();
$timestamp = $params['timestamp'];
$appSecret = $host . $timestamp;
// 添加密钥
$signStr = rtrim($signStr, '&') . $appSecret;
// 生成本地签名使用MD5签名算法
$localSign = md5($signStr);
// 比对签名
if ($requestSign !== $localSign) {
$this->error('签名验证失败');
}
}
/**
* 返回错误信息
* @param string $msg 错误信息
@ -107,10 +119,10 @@ class Allow
{
$result = [
'status' => $code,
'msg' => $msg,
'msg' => $msg,
'data' => null
];
$response = Response::create($result, 'json', $code);
throw new HttpResponseException($response);
}
@ -124,4 +136,56 @@ class Allow
{
}
/**
* 获取路径白名单
*
* @return array 白名单路径列表
*/
protected function getWhitelistPaths()
{
// 1. 默认白名单路径(如支付回调通知等)
$defaultWhitelist = [
'notify/*', // 支付回调等通知
'health', // 健康检查
'debug', // 调试接口
'generate_urllinks',
];
// 2. 从配置文件中获取白名单路径
try {
$configWhitelist = Config::get('api.whitelist_paths', []);
if (!empty($configWhitelist) && is_array($configWhitelist)) {
return array_merge($defaultWhitelist, $configWhitelist);
}
} catch (\Exception $e) {
\think\facade\Log::error('获取API白名单路径配置失败: ' . $e->getMessage());
}
return $defaultWhitelist;
}
/**
* 路径匹配检查
*
* @param string $pattern 白名单路径模式
* @param string $path 请求路径
* @return bool 是否匹配
*/
protected function pathMatch($pattern, $path)
{
// 完全匹配
if ($pattern === $path) {
return true;
}
// 通配符匹配 (例如: 'notify/*')
if (strpos($pattern, '*') !== false) {
$pattern = str_replace('*', '.*', $pattern);
$pattern = '/^' . str_replace('/', '\/', $pattern) . '$/i';
return preg_match($pattern, $path);
}
return false;
}
}

View File

@ -98,8 +98,8 @@ class PaymentCalculator
->where('addtime', '<=', $today_end)
->count();
if ($today_count >= $daily_coupon_limit) {
// return ['status' => 0, 'msg' => '今日优惠券次数已达上限'];
$is_daily_coupon = false;
return ['status' => 0, 'msg' => '今日优惠券次数已达上限'];
// $is_daily_coupon = false;
}
}
if ($is_daily_coupon) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB