中间件
🌐 Middleware
Mastra 服务器可以在 API 路由处理程序被调用之前或之后执行自定义中间件函数。这对于身份验证、日志记录、注入特定请求的上下文或添加 CORS 头等操作非常有用。
🌐 Mastra servers can execute custom middleware functions before or after an API route handler is invoked. This is useful for things like authentication, logging, injecting request-specific context or adding CORS headers.
中间件接收 Hono Context (c) 和一个 next 函数。如果它返回一个 Response,请求将被中断。调用 next() 会继续处理下一个中间件或路由处理器。
🌐 A middleware receives the Hono Context (c) and a next
function. If it returns a Response the request is short-circuited. Calling
next() continues processing the next middleware or route handler.
import { Mastra } from "@mastra/core";
export const mastra = new Mastra({
server: {
middleware: [
{
handler: async (c, next) => {
// Example: Add authentication check
const authHeader = c.req.header("Authorization");
if (!authHeader) {
return new Response("Unauthorized", { status: 401 });
}
await next();
},
path: "/api/*",
},
// Add a global request logger
async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
},
],
},
});
要将中间件附加到单个路由,请将 middleware 选项传递给 registerApiRoute :
🌐 To attach middleware to a single route pass the middleware option to
registerApiRoute:
registerApiRoute("/my-custom-route", {
method: "GET",
middleware: [
async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
},
],
handler: async (c) => {
const mastra = c.get("mastra");
return c.json({ message: "Hello, world!" });
},
});
常见例子Direct link to 常见例子
🌐 Common examples
使用 RequestContextDirect link to using-requestcontext
🌐 Using RequestContext
你可以通过从请求中提取信息,在服务器中间件中动态填充 RequestContext。在这个例子中,temperature-unit 是根据 Cloudflare 的 CF-IPCountry 头设置的,以确保响应与用户的语言环境匹配。
🌐 You can populate RequestContext dynamically in server middleware by extracting information from the request. In this example, the temperature-unit is set based on the Cloudflare CF-IPCountry header to ensure responses match the user's locale.
import { Mastra } from "@mastra/core";
import { RequestContext } from "@mastra/core/request-context";
import { testWeatherAgent } from "./agents/test-weather-agent";
export const mastra = new Mastra({
agents: { testWeatherAgent },
server: {
middleware: [
async (context, next) => {
const country = context.req.header("CF-IPCountry");
const requestContext = context.get("requestContext");
requestContext.set(
"temperature-unit",
country === "US" ? "fahrenheit" : "celsius",
);
await next();
},
],
},
});
验证Direct link to 验证
🌐 Authentication
{
handler: async (c, next) => {
const authHeader = c.req.header('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return new Response('Unauthorized', { status: 401 });
}
// Validate token here
await next();
},
path: '/api/*',
}
授权(用户隔离)Direct link to 授权(用户隔离)
🌐 Authorization (User Isolation)
身份验证用来确认用户的身份。授权则控制他们可以访问的内容。如果没有授权中间件,经过身份验证的用户可能通过猜测 ID 或操作 resourceId 参数访问其他用户的帖子。
🌐 Authentication verifies who the user is. Authorization controls what they can access. Without authorization middleware, an authenticated user could access other users' threads by guessing IDs or manipulating the resourceId parameter.
Mastra 提供了保留的上下文键,当这些键被中间件设置时,它们会优先于客户端提供的值。服务器会在内存和代理端点自动强制执行这些键:
🌐 Mastra provides reserved context keys that, when set by middleware, take precedence over client-provided values. The server automatically enforces these keys across memory and agent endpoints:
import { Mastra } from "@mastra/core";
import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
export const mastra = new Mastra({
server: {
auth: {
authenticateToken: async (token) => {
// Your auth logic returns the user
return verifyToken(token); // { id: 'user-123', ... }
},
},
middleware: [
{
path: '/api/*',
handler: async (c, next) => {
const requestContext = c.get('requestContext');
const user = requestContext.get('user');
if (!user) {
return c.json({ error: 'Unauthorized' }, 401);
}
// Force all API operations to use this user's ID
// This takes precedence over any client-provided resourceId
requestContext.set(MASTRA_RESOURCE_ID_KEY, user.id);
return next();
},
},
],
},
});
使用此中间件,服务器会自动:
🌐 With this middleware, the server automatically:
- 筛选主题列表 仅返回用户拥有的主题
- 验证线程访问权限,如果访问其他用户的线程则返回 403
- 强制线程创建 使用经过身份验证的用户ID
- 验证消息操作,包括删除,确保消息属于拥有的线程
即使客户端通过了 ?resourceId=other-user-id,中间件设置的值也优先。试图访问其他用户拥有的线程或消息将返回 403 错误。
🌐 Even if a client passes ?resourceId=other-user-id, the middleware-set value takes precedence. Attempts to access threads or messages owned by other users will return a 403 error.
使用 MASTRA_THREAD_ID_KEYDirect link to using-mastrathreadidkey
🌐 Using MASTRA_THREAD_ID_KEY
你也可以设置 MASTRA_THREAD_ID_KEY 来覆盖客户端提供的线程 ID:
🌐 You can also set MASTRA_THREAD_ID_KEY to override the client-provided thread ID:
import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
// Force operations to use a specific thread
requestContext.set(MASTRA_THREAD_ID_KEY, validatedThreadId);
当你想将操作限制在通过其他方式验证过的特定线程时,这很有用。
🌐 This is useful when you want to restrict operations to a specific thread that you've validated through other means.
跨域资源共享支持Direct link to 跨域资源共享支持
🌐 CORS support
{
handler: async (c, next) => {
c.header('Access-Control-Allow-Origin', '*');
c.header(
'Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE, OPTIONS',
);
c.header(
'Access-Control-Allow-Headers',
'Content-Type, Authorization',
);
if (c.req.method === 'OPTIONS') {
return new Response(null, { status: 204 });
}
await next();
},
}
请求日志记录Direct link to 请求日志记录
🌐 Request logging
{
handler: async (c, next) => {
const start = Date.now();
await next();
const duration = Date.now() - start;
console.log(`${c.req.method} ${c.req.url} - ${duration}ms`);
},
}
特殊 Mastra 头Direct link to 特殊 Mastra 头
🌐 Special Mastra headers
在与 Mastra Cloud 或自定义客户端集成时,中间件可以检查以下头信息以调整行为:
🌐 When integrating with Mastra Cloud or custom clients the following headers can be inspected by middleware to tailor behavior:
{
handler: async (c, next) => {
const isFromMastraCloud = c.req.header('x-mastra-cloud') === 'true';
const clientType = c.req.header('x-mastra-client-type');
const isStudio =
c.req.header('x-studio') === 'true';
if (isFromMastraCloud) {
// Special handling
}
await next();
},
}
x-mastra-cloud:请求来自Mastra云x-mastra-client-type:识别客户端 SDK,例如js或pythonx-studio:请求由 Studio 触发
相关
🌐 Related