GitHub_Trending/ty/typescript-sdk服务器路由:Express集成与中间件链
GitHub_Trending/ty/typescript-sdk服务器路由:Express集成与中间件链
路由架构概述
GitHub_Trending/ty/typescript-sdk的服务器路由系统基于Express框架构建,通过模块化设计实现了Model Context Protocol(MCP)服务器的核心功能。该架构采用分层路由设计,主要包含认证路由和业务路由两大模块,通过中间件链实现请求验证、权限控制和业务逻辑分离。
路由系统的核心实现位于src/server/auth/router.ts,该文件定义了mcpAuthRouter和mcpAuthMetadataRouter两个主要路由构造函数,分别负责认证端点注册和元数据服务。
Express路由集成
基础路由配置
MCP服务器的Express集成遵循"即插即用"设计理念,通过mcpAuthRouter函数快速搭建完整的认证服务端点。典型集成代码如下:
const app = express();
app.use(express.json());
app.use(mcpAuthRouter({
provider: oauthProvider,
issuerUrl: new URL('https://auth.example.com'),
baseUrl: new URL('https://api.example.com'),
scopesSupported: ['mcp:read', 'mcp:write'],
resourceName: 'MCP API Server'
}));
上述代码会自动注册以下标准OAuth端点:
/authorize- 授权码端点/token- 令牌发放端点/revoke- 令牌撤销端点(可选)/register- 客户端注册端点(可选)/.well-known/oauth-authorization-server- 授权服务器元数据
动态路由生成
路由系统的核心特性是动态端点生成,通过解析元数据自动配置路由路径。关键实现代码位于src/server/auth/router.ts第122-161行:
router.use(
new URL(oauthMetadata.authorization_endpoint).pathname,
authorizationHandler({ provider: options.provider, ...options.authorizationOptions })
);
router.use(
new URL(oauthMetadata.token_endpoint).pathname,
tokenHandler({ provider: options.provider, ...options.tokenOptions })
);
if (oauthMetadata.registration_endpoint) {
router.use(
new URL(oauthMetadata.registration_endpoint).pathname,
clientRegistrationHandler({
clientsStore: options.provider.clientsStore,
...options.clientRegistrationOptions,
})
);
}
这种设计允许通过修改元数据动态调整端点路径,无需手动修改路由配置。
中间件链设计
认证中间件层次
MCP服务器实现了多层中间件认证机制,主要包含客户端认证和令牌认证两种类型:
1. 客户端认证中间件
src/server/auth/middleware/clientAuth.ts实现了客户端身份验证逻辑,通过authenticateClient中间件验证客户端ID和密钥:
export function authenticateClient({ clientsStore }: ClientAuthenticationMiddlewareOptions): RequestHandler {
return async (req, res, next) => {
try {
const result = ClientAuthenticatedRequestSchema.safeParse(req.body);
if (!result.success) {
throw new InvalidRequestError(String(result.error));
}
const { client_id, client_secret } = result.data;
const client = await clientsStore.getClient(client_id);
if (!client) {
throw new InvalidClientError("Invalid client_id");
}
// 客户端密钥验证逻辑...
req.client = client;
next();
} catch (error) {
// 错误处理...
}
}
}
该中间件会将验证通过的客户端信息附加到req.client属性,供后续处理使用。
2. 令牌认证中间件
src/server/auth/middleware/bearerAuth.ts实现了Bearer令牌验证机制,通过requireBearerAuth中间件验证访问令牌:
export function requireBearerAuth({ verifier, requiredScopes = [], resourceMetadataUrl }: BearerAuthMiddlewareOptions): RequestHandler {
return async (req, res, next) => {
try {
const authHeader = req.headers.authorization;
if (!authHeader) {
throw new InvalidTokenError("Missing Authorization header");
}
const [type, token] = authHeader.split(' ');
if (type.toLowerCase() !== 'bearer' || !token) {
throw new InvalidTokenError("Invalid Authorization header format");
}
const authInfo = await verifier.verifyAccessToken(token);
// 令牌有效期和作用域验证...
req.auth = authInfo;
next();
} catch (error) {
// 错误处理...
}
};
}
中间件链组装
在实际应用中,中间件通过链式调用形成完整的认证流程。src/examples/server/simpleStreamableHttp.ts展示了典型的中间件配置:
// 设置认证中间件
if (useOAuth && authMiddleware) {
app.post('/mcp', authMiddleware, mcpPostHandler);
app.get('/mcp', authMiddleware, mcpGetHandler);
app.delete('/mcp', authMiddleware, mcpDeleteHandler);
} else {
app.post('/mcp', mcpPostHandler);
app.get('/mcp', mcpGetHandler);
app.delete('/mcp', mcpDeleteHandler);
}
这种配置实现了"可选认证"模式,允许根据部署环境灵活启用或禁用OAuth保护。
实战案例:MCP端点保护
以下是一个完整的MCP服务器路由配置示例,展示了如何组合路由和中间件保护API端点:
// 创建Express应用
const app = express();
app.use(express.json());
// 配置CORS
app.use(cors({
origin: '*',
exposedHeaders: ["Mcp-Session-Id"]
}));
// 设置OAuth认证
const mcpServerUrl = new URL(`http://localhost:3000/mcp`);
const oauthMetadata = setupAuthServer({
authServerUrl: new URL(`http://localhost:3001`),
mcpServerUrl
});
// 创建令牌验证中间件
const authMiddleware = requireBearerAuth({
verifier: tokenVerifier,
requiredScopes: ['mcp:tools'],
resourceMetadataUrl: getOAuthProtectedResourceMetadataUrl(mcpServerUrl),
});
// 注册认证元数据路由
app.use(mcpAuthMetadataRouter({
oauthMetadata,
resourceServerUrl: mcpServerUrl,
scopesSupported: ['mcp:tools'],
resourceName: 'MCP Demo Server',
}));
// 保护MCP端点
app.post('/mcp', authMiddleware, mcpPostHandler);
app.get('/mcp', authMiddleware, mcpGetHandler);
app.delete('/mcp', authMiddleware, mcpDeleteHandler);
// 启动服务器
app.listen(3000, () => {
console.log('MCP Server running on port 3000');
});
这个配置实现了:
- 完整的OAuth2认证流程
- MCP协议所需的POST/GET/DELETE端点
- 基于Bearer令牌的访问控制
- 符合RFC规范的元数据服务
路由与中间件最佳实践
1. 路由组织原则
- 按功能模块划分路由:将认证路由、业务路由和元数据路由分离管理
- 使用路由前缀:为不同版本或功能域的API设置路由前缀(如
/v1/mcp) - 集中式错误处理:在路由顶层实现统一的错误捕获和响应格式化
2. 中间件使用建议
- 中间件优先级:认证中间件 → 日志中间件 → 业务中间件
- 条件中间件:根据环境变量或配置动态启用中间件(如开发环境禁用认证)
- 中间件组合:使用
express.Router()创建可复用的中间件链
3. 安全性考虑
- 输入验证:对所有请求参数进行严格验证,参考src/server/auth/middleware/clientAuth.ts中的Zod模式验证
- 令牌管理:实现令牌轮换和撤销机制,参考src/server/auth/handlers/revoke.ts
- 作用域控制:基于最小权限原则设计作用域,在src/server/auth/middleware/bearerAuth.ts中配置必要的作用域检查
总结
GitHub_Trending/ty/typescript-sdk的服务器路由系统通过Express框架实现了灵活且安全的API端点管理。其核心优势在于:
- 模块化设计:通过
mcpAuthRouter和mcpAuthMetadataRouter实现路由功能的解耦 - 动态路由生成:基于元数据自动配置端点,提高可维护性
- 多层认证中间件:客户端认证与令牌认证相结合,满足不同场景需求
- 可扩展性:通过中间件链和路由前缀支持API版本管理和功能扩展
开发人员可以通过修改src/server/auth/router.ts中的路由配置和src/server/auth/middleware/目录下的中间件实现,定制符合特定业务需求的认证和路由策略。
更多推荐


所有评论(0)