manghe/app/api/middleware/Allow.php
2025-04-07 15:29:55 +00:00

127 lines
3.4 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
*
* User: anker
* Date: 4/22/22
* Email: <13408046898@163.com>
**/
namespace app\api\middleware;
use think\facade\Config;
use think\exception\HttpResponseException;
use think\Response;
class Allow
{
public function handle($request, \Closure $next)
{
// 处理跨域
header('Access-Control-Allow-Origin: *');
header('Access-Control-Max-Age: 1800');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With,access-token,token,adid,clickid,client');
// 第一次预请求不管
if (strtoupper($request->method()) == "OPTIONS") {
exit;
}
// 对GET请求进行签名验证
if (strtoupper($request->method()) == "GET") {
$this->verifySignature($request);
}
// 处理跨域
// 后置中间件
$response = $next($request);
return $response;
}
/**
* 验证请求签名
* @param \think\Request $request
* @return void
*/
protected function verifySignature($request)
{
// 获取所有GET参数
$params = $request->get();
// 如果请求中携带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 错误信息
* @param int $code 错误码
* @return void
*/
protected function error($msg, $code = 0)
{
$result = [
'status' => $code,
'msg' => $msg,
'data' => null
];
$response = Response::create($result, 'json', $code);
throw new HttpResponseException($response);
}
/**
* 中间件结束调度
* @param \think\Response $response
* @return void
*/
public function end(\think\Response $response)
{
}
}