尧图精选

Mastra 集成 Firebase 认证:@mastra/auth-firebase 的 ID Token 验证与 Firestore 授权实现指南

🕒 发布时间:2026/9/14 10:41:11 📁 来源:尧图网络
Mastra 集成 Firebase 认证mastra/auth-firebase 的 ID Token 验证与 Firestore 授权实现指南【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本篇指南基于 Mastra 仓库中的mastra/auth-firebase包文档展开讲解如何在已有 Firebase Authentication 的用户体系下让 Mastra 服务端验证 Firebase ID Token 并使用 Firestore 数据做授权决策。读完后你将掌握MastraAuthFirebase的完整配置方式环境变量与构造参数、默认的user_access授权模型、可自定义的authorizeUser钩子以及客户端通过Authorization: Bearer idToken发起受保护请求的完整链路并能从源码层面理解每个配置项的实际行为。一、包定位它解决什么问题auth/firebase/README.md 对该包的一句话定义是mastra/auth-firebase负责验证 Firebase ID Token并可借助 Firestore 数据做出授权authorization决策。适用场景很明确——Firebase Authentication 已经在管理你的用户体系而 Mastra 的 API 端点Agent、Workflow 等需要尊重这些既有身份而不是引入一套独立的登录态。从 auth/firebase/package.json 可以看到该包的关键元信息包名mastra/auth-firebase当前版本1.1.2核心依赖是firebase-admin: ^13.7.0即所有验证逻辑都建立在 Firebase Admin SDK 之上运行时要求node 22.13.0同时产出 ESMdist/index.js与 CJSdist/index.cjs两种格式。在 Mastra 的认证体系中所有认证提供者都继承自 packages/_internals/auth/src/provider/index.ts 中的抽象基类MastraAuthProviderTUser。Firebase 提供的用户类型被固定为 Firebase 的DecodedIdTokentype FirebaseUser admin.auth.DecodedIdToken;也就是说后续所有授权回调里拿到的user就是标准 JWT 解码后的 Firebase 用户对象含uid、email、email_verified、name、picture、auth_time及标准 JWT claims。二、安装与前置条件安装命令继承自 auth/firebase/README.mdnpm install mastra/auth-firebase仓库官方集成文档 docs/src/content/en/integrations/auth/firebase.mdx 补充了完整的前置条件实际落地前需要在 Firebase Console 中创建项目并启用 Authentication、配置好登录方式Google、Email/Password 等从 Project Settings Service Accounts 生成并下载服务账号 JSON 密钥文件在.env中配置环境变量FIREBASE_SERVICE_ACCOUNT/path/to/your/service-account-key.json FIRESTORE_DATABASE_ID(default) # 备选环境变量名 # FIREBASE_DATABASE_ID(default)文档同时提醒服务账号 JSON 包含可验证 ID Token 的服务端凭证必须妥善保存、绝不能提交进版本库。三、服务端接入两种初始化方式3.1 纯环境变量驱动README 基础用法按 auth/firebase/README.md 的示例设置好FIREBASE_SERVICE_ACCOUNT与按需的FIRESTORE_DATABASE_ID后可以直接零参数构造import { Mastra } from mastra/core/mastra; import { MastraAuthFirebase } from mastra/auth-firebase; export const mastra new Mastra({ server: { auth: new MastraAuthFirebase(), }, });3.2 显式构造参数也可以不依赖环境变量直接在构造函数中指定官方集成文档中的 Custom configuration 示例import { Mastra } from mastra/core; import { MastraAuthFirebase } from mastra/auth-firebase; export const mastra new Mastra({ server: { auth: new MastraAuthFirebase({ serviceAccount: /path/to/service-account.json, databaseId: your-database-id, }), }, });四、配置项与环境变量全集综合 auth/firebase/src/index.ts 的MastraAuthFirebaseOptions接口、基类MastraAuthProviderOptions以及参考文档 docs/src/content/en/reference/auth/firebase.mdxMastraAuthFirebase支持以下构造参数参数类型默认值说明serviceAccountstringprocess.env.FIREBASE_SERVICE_ACCOUNTFirebase 服务账号 JSON 文件的路径用于服务端验证 ID TokendatabaseIdstringprocess.env.FIRESTORE_DATABASE_ID \|\| process.env.FIREBASE_DATABASE_IDFirestore 数据库 ID默认库通常为(default)namestringfirebase认证提供者实例的自定义名称authorizeUser(user: FirebaseUser) Promiseboolean \| booleanFirestoreuser_access检查自定义授权函数在 Token 验证成功后被调用此外基类还提供几个通用选项见 packages/_internals/auth/src/provider/index.ts#L19-L31同样可以通过构造函数传入protected/public声明受保护路径与放行路径列表用于路由级别的访问控制mapUserToResourceId把已认证用户映射为 memory 的 resource id供记忆/会话隔离使用。4.1 配置解析顺序源码视角auth/firebase/src/index.ts#L18-L33 中构造函数的取值逻辑值得逐行看清constructor(options?: MastraAuthFirebaseOptions) { super({ name: options?.name ?? firebase }); this.serviceAccount options?.serviceAccount ?? process.env.FIREBASE_SERVICE_ACCOUNT; this.databaseId options?.databaseId ?? process.env.FIRESTORE_DATABASE_ID ?? process.env.FIREBASE_DATABASE_ID; if (!admin.apps.length) { admin.initializeApp({ credential: this.serviceAccount ? admin.credential.cert(this.serviceAccount) : admin.credential.applicationDefault(), }); } this.registerOptions(options); }三个值得注意的实现细节构造参数优先于环境变量databaseId有两个环境变量来源FIRESTORE_DATABASE_ID优先FIREBASE_DATABASE_ID作为兼容别名兜底Firebase Admin 只在进程内初始化一次admin.apps.length非零时跳过initializeApp避免与项目中其他使用 firebase-admin 的模块冲突重复初始化会直接抛异常凭证的两种形态提供了serviceAccount时走admin.credential.cert(...)对应本地 JSON 文件路径完全没配时退化为admin.credential.applicationDefault()即云环境如 GCP下的 Application Default Credentials。这一点意味着在无环境变量的托管环境中包也能借助平台自带凭证工作但本地开发几乎必须提供 JSON 路径。最后调用this.registerOptions(options)完成基类钩子注册。五、认证与授权两步走的请求处理模型基类MastraAuthProvider把一次受保护请求拆成两个抽象方法authenticateToken验证身份与authorizeUser判定权限Firebase 包分别实现了这两步。5.1 authenticateTokenID Token 验证auth/firebase/src/index.ts#L35-L38async authenticateToken(token: string): PromiseFirebaseUser | null { const decoded await admin.auth().verifyIdToken(token); return decoded; }逻辑直接委托给 Firebase Admin 的verifyIdToken校验签名、签发者、有效期等 JWT 属性成功则返回DecodedIdToken即上文FirebaseUser失败时 Admin SDK 会抛出异常由 Mastra 服务层的认证中间件将其转换为未授权响应。测试用例 auth/firebase/src/index.test.ts#L71-L100 分别覆盖了验证成功返回解码对象、以及验证失败mock 抛Invalid token两条路径。5.2 authorizeUser基于 Firestore 的默认授权auth/firebase/src/index.ts#L40-L50async authorizeUser(user: FirebaseUser) { const db this.databaseId ? getFirestore(this.databaseId) : getFirestore(); const userAccess await db.doc(/user_access/${user.uid}).get(); const userAccessData userAccess.data(); if (!userAccessData) { return false; } return true; }默认的授权模型是一条非常简洁的Firestore 名单机制Token 验证通过后用user.uid拼接出文档路径/user_access/${uid}该文档存在即授权通过不存在即拒绝使用的 Firestore 实例由databaseId或环境变量决定未配置时使用默认数据库。对应官方文档中的 Firestore 结构示意user_access/ {user_uid_1}/ // 文档存在 该用户已授权 {user_uid_2}/ // 文档存在 该用户已授权也就是说管理员只要在 Firestore 的user_access集合里为某个uid建一个文档内容可为任意数据判断只看data()是否为null该用户就能访问删除文档即回收权限。测试文件 auth/firebase/src/index.test.ts#L102-L135 对这两种结果分别做了断言文档有数据返回truedata()为null返回false。5.3 自定义授权逻辑默认 Firestore 名单不够用时例如想按邮箱域、角色 claims 判断通过构造参数传入authorizeUser即可整体替换——官方文档给出的示例import { MastraAuthFirebase } from mastra/auth-firebase; const firebaseAuth new MastraAuthFirebase({ authorizeUser: async user { // 自定义授权逻辑 return user.email?.endsWith(yourcompany.com) || false; }, });从源码看该钩子的生效链路是构造函数先super(options)基类在构造时若发现options.authorizeUser就执行this.authorizeUser options.authorizeUser.bind(this)随后registerOptionspackages/_internals/auth/src/provider/index.ts#L104-L117再次确认绑定保证自定义函数覆盖掉默认的 Firestore 实现。测试用例 auth/firebase/src/index.test.ts#L137-L156 验证了自定义逻辑下 admin 用户放行、普通用户与无权限用户拒绝的行为。六、测试覆盖情况aith/firebase/src/index.test.ts 通过 mockfirebase-admin与firebase-admin/firestore在不连真实 Firebase 的情况下验证了四个关键行为初始化显式传入serviceAccount/ 依赖环境变量两种方式都应调用admin.credential.cert(...)并完成initializeAppauthenticateToken成功时verifyIdToken被原样传入 token 并返回解码对象失败抛错时按约定视为未通过authorizeUser 默认实现严格断言查询路径为/user_access/${uid}文档存在返回true、不存在返回falseauthorizeUser 可覆盖传入自定义函数后完全走自定义逻辑。这意味着包的核心契约配置优先级、Token 验证委托、user_access名单路径、钩子可替换性都有回归测试守护。七、客户端集成把 ID Token 放进 Authorization 头服务端只认Authorization头里的 Bearer Token因此客户端侧需要完成三件事初始化 Firebase SDK、登录并取 ID Token、把 Token 注入 Mastra 客户端。官方集成文档给出了完整参考实现7.1 初始化 Firebase 客户端并登录import { initializeApp } from firebase/app; import { getAuth, GoogleAuthProvider } from firebase/auth; const firebaseConfig { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, }; const app initializeApp(firebaseConfig); export const auth getAuth(app); export const googleProvider new GoogleAuthProvider();import { signInWithPopup, signOut, User } from firebase/auth; import { auth, googleProvider } from ./firebase; export const signInWithGoogle async () { try { const result await signInWithPopup(auth, googleProvider); return result.user; } catch (error) { console.error(Error signing in:, error); throw error; } }; export const getIdToken async (user: User) { try { const idToken await user.getIdToken(); return idToken; } catch (error) { console.error(Error getting ID token:, error); throw error; } };7.2 创建带 Bearer Token 的 MastraClient启用auth后所有经MastraClient发出的请求都必须携带 Firebase ID Tokenimport { MastraClient } from mastra/client-js; export const createMastraClient (idToken: string) { return new MastraClient({ baseUrl: https://mastra-api-url, headers: { Authorization: Bearer ${idToken}, }, }); };在 React 组件中即可发起受保护调用use client; import { useAuthState } from react-firebase-hooks/auth; import { auth } from ../lib/firebase; import { getIdToken } from ../lib/auth; import { createMastraClient } from ../lib/mastra/mastra-client; export const TestAgent () { const [user] useAuthState(auth); async function handleClick() { if (!user) return; const token await getIdToken(user); const client createMastraClient(token); const weatherAgent client.getAgent(weatherAgent); const response await weatherAgent.generate(Whats the weather like in New York); console.log({ response }); } return ( button onClick{handleClick} disabled{!user} Test Agent /button ); };不想走 SDK 时也可以直接对 HTTP API 发请求curl -X POST http://localhost:4111/api/agents/weatherAgent/generate \ -H Content-Type: application/json \ -H Authorization: Bearer your-firebase-id-token \ -d { messages: Weather in London }注意 ID Token 是短期 JWT客户端应通过user.getIdToken()按需获取Firebase SDK 会自动缓存与刷新而不是一次取回后长期复用。八、适用边界与小结使用mastra/auth-firebase前请确认以下前提均以当前仓库实现为准用户体系已由 Firebase Authentication 管理客户端能稳定取得 ID Token服务端可访问服务账号 JSONFIREBASE_SERVICE_ACCOUNT或运行在具备 ADC 的云平台默认授权依赖 Firestore 中的user_access集合需要为该集合建立文档级的开通/回收流程若不需要 Firestore 参与务必传入自定义authorizeUser否则会因查不到user_access文档而拒绝所有请求Node 版本需满足 22.13.0。整体而言这个包把 Firebase 生态的身份验证verifyIdToken与 Mastra 的统一认证抽象authenticateTokenauthorizeUser两步契约做了最小而清晰的桥接配置上环境变量优先开箱即用、构造参数可显式覆盖授权上Firestore 文档存在即放行、钩子可整体替换。相关实现与测试分别位于 auth/firebase/src/index.ts 与 auth/firebase/src/index.test.ts版本历史见 auth/firebase/CHANGELOG.md更完整的操作文档见仓库内 docs/src/content/en/integrations/auth/firebase.mdx 与 docs/src/content/en/reference/auth/firebase.mdx。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →