Files
zyt/server/app/mcp/service/Guard.php
T
2026-09-24 09:45:44 +08:00

45 lines
1.8 KiB
PHP
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
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;
}
}