method(), ['GET', 'HEAD', 'OPTIONS'])) { // MCP 内部分发豁免(唯一豁免通道,安全性论证): // 1. mcp_internal 标记只能由服务端写入 login 缓存(McpDispatch 生成的一次性 // creator token),攻击者需先具备服务器内部写缓存能力才可伪造; // 2. 跨站表单/HTML 场景无法携带 Authorization 自定义头(浏览器表单不透传该头), // 对该头的 CSRF 攻击模型本身不成立; // 3. 豁免标记与 5 分钟一次性 token 同生命周期:McpDispatch 调用结束即删 // (try/finally),缓存 TTL 到期自动失效,不残留长期豁免通道。 $authorization = $request->header('authorization', ''); $token = (strpos($authorization, ' ') !== false) ? trim(explode(' ', $authorization)[1]) : ''; if (!empty($token)) { $cached = \think\facade\Cache::store('login')->get($token); if (!empty($cached['mcp_internal'])) { return $next($request); // MCP 内部分发标记,跳过 CSRF(一次性短时 token) } } // 跨域校验 $refererUrl = $request->header('REFERER', null); $refererInfo = parse_url($refererUrl); $host = $request->host(true); if (!isset($refererInfo['host']) || $refererInfo['host'] != $host) { $this->error('当前请求不合法!'); } // CSRF校验 // @todo 兼容CK编辑器上传功能 $ckCsrfToken = $request->post('ckCsrfToken', null); $data = !empty($ckCsrfToken) ? ['__token__' => $ckCsrfToken] : []; $check = $request->checkToken('__token__', $data); if (!$check) { $this->error('请求验证失败,请重新刷新页面!'); } } } return $next($request); } }