148 lines
4.5 KiB
PHP
148 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace app\common\http\middleware;
|
|
|
|
use app\common\service\JsonService;
|
|
use Closure;
|
|
use think\facade\Log;
|
|
|
|
class WechatAllowMiddleware
|
|
{
|
|
private const ALLOWED_HEADERS = [
|
|
'Authorization', 'Sec-Fetch-Mode', 'DNT', 'X-Mx-ReqToken', 'Keep-Alive', 'User-Agent',
|
|
'If-Match', 'If-None-Match', 'If-Unmodified-Since', 'X-Requested-With', 'If-Modified-Since',
|
|
'Cache-Control', 'Content-Type', 'Accept-Language', 'Origin', 'Accept-Encoding', 'Access-Token',
|
|
'token', 'version', 'X-Requested-With', 'X-CSRF-TOKEN', 'Platform', 'Accept', 'Contenttype', 'Referer'
|
|
];
|
|
|
|
public function handle($request, Closure $next, ?array $header = []): mixed
|
|
{
|
|
// 记录调试信息
|
|
Log::info('WechatAllowMiddleware executed. Method: ' . $request->method() . ', Origin: ' . $request->header('origin'));
|
|
|
|
// 设置跨域头
|
|
$this->setCorsHeaders($request);
|
|
|
|
// 处理 OPTIONS 预检请求
|
|
if (strtoupper($request->method()) === 'OPTIONS') {
|
|
Log::info('OPTIONS request handled');
|
|
return $this->handleOptionsRequest();
|
|
}
|
|
|
|
// 安装检测
|
|
$install = file_exists(root_path() . '/config/install.lock');
|
|
if (!$install) {
|
|
return JsonService::fail('程序未安装', [], -2);
|
|
}
|
|
|
|
$response = $next($request);
|
|
|
|
// 确保响应也有跨域头
|
|
return $this->addCorsToResponse($response, $request);
|
|
}
|
|
|
|
/**
|
|
* 设置跨域头信息
|
|
*/
|
|
private function setCorsHeaders($request): void
|
|
{
|
|
$origin = $request->header('origin', '');
|
|
|
|
// 允许的域名列表
|
|
$allowedOrigins = [
|
|
'http://localhost:9002',
|
|
'http://localhost:9001',
|
|
'http://localhost:9000',
|
|
'https://localhost:9000',
|
|
'https://localhost:9001',
|
|
'https://localhost:9002',
|
|
'https://localhost:9003',
|
|
'http://127.0.0.1:9002',
|
|
'http://127.0.0.1:9001',
|
|
'http://127.0.0.1:9000',
|
|
'http://127.0.0.1:9003',
|
|
'https://cz.stnav.com',
|
|
'https://www.cztnav.com',
|
|
'http://localhost:9001/h5#/'
|
|
];
|
|
|
|
// 验证来源
|
|
$allowOrigin = $this->validateOrigin($origin, $allowedOrigins);
|
|
|
|
$headers = [
|
|
'Access-Control-Allow-Origin' => $allowOrigin,
|
|
'Access-Control-Allow-Headers' => implode(', ', self::ALLOWED_HEADERS),
|
|
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
|
|
'Access-Control-Max-Age' => '86400',
|
|
'Access-Control-Allow-Credentials' => 'true'
|
|
];
|
|
|
|
foreach ($headers as $key => $value) {
|
|
header("$key: $value");
|
|
}
|
|
|
|
Log::info('CORS headers set: ' . json_encode($headers));
|
|
}
|
|
|
|
/**
|
|
* 验证来源域名
|
|
*/
|
|
private function validateOrigin($origin, $allowedOrigins): string
|
|
{
|
|
if (empty($origin)) {
|
|
return $allowedOrigins[0] ?? '*';
|
|
}
|
|
|
|
foreach ($allowedOrigins as $allowed) {
|
|
if ($origin === $allowed) {
|
|
return $origin;
|
|
}
|
|
}
|
|
|
|
return $allowedOrigins[0] ?? '*';
|
|
}
|
|
|
|
/**
|
|
* 正确处理 OPTIONS 请求
|
|
*/
|
|
private function handleOptionsRequest()
|
|
{
|
|
Log::info('Returning OPTIONS response with 200 status');
|
|
return response()
|
|
->code(200)
|
|
->header((array)'Content-Type', 'text/plain')
|
|
->header((array)'Content-Length', '0');
|
|
}
|
|
|
|
/**
|
|
* 为响应添加跨域头
|
|
*/
|
|
private function addCorsToResponse($response, $request)
|
|
{
|
|
$origin = $request->header('origin', '');
|
|
$allowedOrigins = [
|
|
'http://localhost:9001',
|
|
'http://localhost:9002',
|
|
'https://localhost:9001',
|
|
'https://localhost:9002',
|
|
'https://localhost:9003',
|
|
'http://127.0.0.1:9001',
|
|
'http://127.0.0.1:9002',
|
|
'http://127.0.0.1:9003',
|
|
'https://cz.stnav.com',
|
|
'https://www.cztnav.com',
|
|
'http://localhost:9000',
|
|
'https://localhost:9000',
|
|
'http://127.0.0.1:9000'
|
|
];
|
|
|
|
$allowOrigin = $this->validateOrigin($origin, $allowedOrigins);
|
|
|
|
$response->header([
|
|
'Access-Control-Allow-Origin' => $allowOrigin,
|
|
'Access-Control-Allow-Credentials' => 'true'
|
|
]);
|
|
|
|
return $response;
|
|
}
|
|
} |