This commit is contained in:
gr
2026-09-24 09:45:44 +08:00
parent dbf474ddd7
commit bd22e5f476
38 changed files with 19152 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace app\mcp\service;
use think\Request;
use think\Response;
/**
* 请求级防护:浏览器 Origin 校验(防 DNS 重绑定)、来源 IP 白名单、401 响应格式。
*/
class Guard
{
/** 返回 null 表示放行,否则返回 [HTTP 状态码, 原因, reason] */
public static function check(Request $request): ?array
{
$origin = trim((string) $request->header('origin', ''));
if ($origin !== '' && !in_array(rtrim($origin, '/'), array_map(static fn ($o) => rtrim($o, '/'), McpConfig::allowedOrigins()), true)) {
return [403, 'Origin not allowed', 'origin_not_allowed'];
}
$ips = McpConfig::allowedIps();
if ($ips && !in_array($request->ip(), $ips, true)) {
return [403, '来源 IP 不在 AI 助手白名单内', 'ip_not_allowed'];
}
return null;
}
/** MCP 端点的 401:JSON-RPC 错误体 + WWW-Authenticate */
public static function unauthorized(McpException $e): Response
{
$body = ['jsonrpc' => '2.0', 'id' => null, 'error' => ['code' => -32001, 'message' => $e->getMessage(), 'data' => ['reason' => $e->reason]]];
return json($body, 401)->header(['WWW-Authenticate' => 'Bearer error="invalid_token", error_description="' . $e->reason . '"']);
}
/** REST 接口的统一信封(与后台 JsonService 一致) */
public static function envelope(int $code, string $msg, $data = [], int $httpStatus = 200, int $show = 0): Response
{
$response = json(['code' => $code, 'show' => $show, 'msg' => $msg, 'data' => $data ?: new \stdClass()], $httpStatus);
if ($httpStatus === 401) {
$response->header(['WWW-Authenticate' => 'Bearer error="invalid_token"']);
}
return $response;
}
}