ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Omi Admin Dashboard 深度指南:基于 Next.js 的内部运营后台架构、鉴权与本地开发全解

2026/9/17 8:32:27 拓冰建站 浏览量
Omi Admin Dashboard 深度指南:基于 Next.js 的内部运营后台架构、鉴权与本地开发全解 Omi Admin Dashboard 深度指南基于 Next.js 的内部运营后台架构、鉴权与本地开发全解【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend导读web/admin是 Omi 项目AI 眼镜助手的内部运营管理后台运行在admin.omi.me采用 Next.js 构建。它以浏览器端 Firebase 登录认证管理员身份并在同源app/api/下暴露受保护的 Next.js Route Handler由服务端统一读取 Firestore、调用 Omi 后端 API 与第三方厂商 API浏览器代码永远不会拿到服务端密钥。本文基于仓库内 web/admin/README.md 展开结合.env.example、lib/auth.ts、lib/dev-auth.ts、Dockerfile与 GitHub Actions 部署工作流等源码系统讲解其本地启动流程、开发鉴权绕过机制、环境变量全量说明、权限模型以及 CI/部署链路读者学完后即可独立完成本地开发、联调、自检与生产部署全流程。一、整体架构浏览器、Route Handler 与服务端的信任边界1.1 三层职责划分从 README 与目录结构可以提炼出后台的经典三层架构客户端app/(protected)/dashboard/**负责渲染内部运营界面analytics、reviews、announcements、fair-use、subscriptions 等数十个页面通过 Firebase 登录获得身份但不在浏览器里直接读取 Firestore也不自行构造鉴权头。根据 web/admin/AGENTS.md 的硬性约定所有网络请求必须经由hooks/useAuthToken.ts统一携带 token。服务端 Route Handlerapp/api/omi/**、app/api/stats/**等每个受保护路由入口都调用verifyAdmin(request)见 lib/auth.ts完成鉴权之后才代表管理员读取 Firestore 或调用 Omi API / 厂商 API。第三方凭证Stripe、PostHog、Typesense、GoAffPro 等只存在于服务端环境变量中浏览器永远接触不到。上游服务Omi 后端 APIbackend/、Firestore、LLM 网关OMI_LLM_GATEWAY_URL以及各类厂商系统。1.2 为什么浏览器拿不到服务端凭证README 明确指出Browser code never receives the server credentials。实现上服务端密钥只在 Route Handler 进程内使用例如 LLM 网关路由只依赖OMI_LLM_GATEWAY_SERVICE_TOKEN服务端令牌而不会持有任何 LLM 提供商的 API Key。这层设计让后台可以安全地聚合管理 Stripe、Shopify、ShipBob、Mixpanel 等敏感系统而不必担心把密钥泄露进 JS bundle。二、本地开发环境搭建UI 快速起步2.1 最小安装步骤README 给出了标准的三步安装cd web/admin cp .env.example .env.local npm ci注意使用npm ci而非npm install它会严格按package-lock.json锁定依赖版本保证与 CI 环境一致。项目核心依赖见 package.jsonNext.js 16、React 18、Firebase 客户端 SDKfirebase11 与 Admin SDKfirebase-admin13、SWR 数据请求、Radix UI 组件库、recharts 图表与 zod 校验。2.2 跳过登录的开发鉴权绕过DEV BYPASS纯 UI 开发不需要真实 Firebase 登录只需在.env.local中设置NEXT_PUBLIC_DEV_BYPASS_AUTH1然后启动npm run dev打开 http://localhost:3000/dashboard 即可。绕过的固定本地身份为dev-admin它会同时提供给客户端和受保护路由处理器对未配置对应服务依赖的 API 卡片页面会显示错误README 已提示API cards whose backing service is not configured will show errors这属于预期行为。实现细节绕过逻辑在 lib/dev-auth.ts 中非常明确export const DEV_BYPASS_ENABLED process.env.NODE_ENV ! production (process.env.NEXT_PUBLIC_DEV_BYPASS_AUTH 1 || process.env.DEV_BYPASS_AUTH 1); export const DEV_BYPASS_UID dev-admin; export const DEV_BYPASS_TOKEN dev-bypass-token;两个关键事实值得注意绕过同时受NODE_ENV ! production和显式开启标志的双重约束在生产构建中被硬性禁用无法通过误设环境变量绕开lib/auth.ts 中服务端只接受Authorization: Bearer dev-bypass-token这一特定令牌并映射到dev-admin其余情况一律走 Firebase ID Token 校验流程。⚠️ README 特别警告不要在.env.local中放入生产凭证。三、对接本地 Omi 后端进行真实联调当需要验证真实的 Omi API 集成时需要把backend/也跑起来按 backend/AGENTS.md 开发者指南操作并使用独立的开发或离线数据环境。在web/admin/.env.local中设置NEXT_PUBLIC_DEV_BYPASS_AUTH1 NEXT_PUBLIC_OMI_API_URLhttp://localhost:8080 OMI_API_SECRET_KEYthe same value as backend ADMIN_KEY3.1 双重凭证的拼接逻辑README 说明了后台的鉴权方式向 Omi 后端发送基础密钥base key与由该密钥 已认证 UID 拼接而成的 token两个值。绕过模式下 UID 恒为dev-admin因此只要本地后端的ADMIN_KEY与OMI_API_SECRET_KEY一致即可通过认证。可对照 lib/services/omi-api/client.ts 中的客户端实现验证实际请求构造方式。⚠️ 危险边界管理员操作会真实修改后端及其数据存储因此该模式严禁指向生产环境。3.2 数据类与外部系统类页面的额外配置不同功能对凭证的需求分档如下功能类别所需配置说明读写 Firestore 的路由FIREBASE_PROJECT_ID、FIREBASE_CLIENT_EMAIL、FIREBASE_PRIVATE_KEY必须是非生产 Firebase 项目使用外部系统的页面对应系统在.env.example中的凭证如 Stripe、PostHog、Typesense、GoAffProLLM 网关路由OMI_LLM_GATEWAY_URL 服务端专用OMI_LLM_GATEWAY_SERVICE_TOKEN服务端只持有网关服务令牌从不接触 LLM 提供商凭证真实登录流程测试NEXT_PUBLIC_FIREBASE_*客户端变量仅绕过模式关闭时才需要四、环境变量全量参考.env.example 逐项解析完整的模板见 web/admin/.env.example按用途可划分为九组这里给出每组的关键变量与使用场景4.1 开发与鉴权NEXT_PUBLIC_DEV_BYPASS_AUTH本地开发入口开关置1免登录进入后台NODE_ENVproduction时被硬禁用。4.2 Firebase 客户端 SDK可公开暴露NEXT_PUBLIC_FIREBASE_API_KEY、NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN、NEXT_PUBLIC_FIREBASE_PROJECT_ID、NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET、NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID、NEXT_PUBLIC_FIREBASE_APP_ID、NEXT_PUBLIC_FIREBASE_VAPID_KEY——这些属于浏览器端安全公开的配置用于真实登录与消息推送。4.3 Firebase Admin SDK服务端专用绝不暴露FIREBASE_PROJECT_ID/FIREBASE_CLIENT_EMAIL/FIREBASE_PRIVATE_KEY服务端校验 Firebase ID Token、读取 Firestore 的adminData/{uid}集合时使用。4.4 Omi 后端 APINEXT_PUBLIC_OMI_API_URLOmi 后端地址本地联调指向http://localhost:8080。OMI_API_SECRET_KEY服务端专用须与后端ADMIN_KEY一致。NEXT_PUBLIC_PLUGINS_APP_ID插件应用标识。4.5 外部系统凭证各页面按需使用StripeSTRIPE_SECRET_KEY对应 lib/stripe.ts 的订阅指标读取。TypesenseTYPESENSE_HOST、TYPESENSE_API_KEY、TYPESENSE_CONVERSATION_COLLECTION对话检索集合名。RedisREDIS_HOST、REDIS_PORT、REDIS_PASSWORD缓存预热使用见 lib/redis.ts。PostgreSQLPOSTGRES_URL。ShipBob / ShopifySHIPBOB_API_KEY、SHOPIFY_STORE、SHOPIFY_ACCESS_TOKEN分销与订阅订单。MixpanelMIXPANEL_SECRET、MIXPANEL_API_BASE。PostHogPOSTHOG_PERSONAL_API_KEY、POSTHOG_PROJECT_ID、POSTHOG_HOST增长指标统计。LLM 网关OMI_LLM_GATEWAY_URL、OMI_LLM_GATEWAY_SERVICE_TOKEN。其他ENCRYPTION_SECRET、GITHUB_TOKEN、GOAFFPRO_ACCESS_TOKEN。4.6 成本核算与定时任务Stats/Infra 页CRON_SECRET受保护的定时缓存预计算任务对应app/api/internal/precompute/route.ts。ADMIN_INFRA_OVERHEAD_MONTHLY、ADMIN_SERVICE_COSTS_JSON估算模式基础设施开销与服务成本表。GCP_BILLING_SA_JSON计费模式服务账号 JSONBigQueryjobUserdataViewer权限留空则走 ambient ADC对应 lib/services/gcp-billing.ts。GCP_BILLING_TABLE计费导出表覆盖项project.dataset.table。ADMIN_ANTHROPIC_COST_API_KEY、ADMIN_OPENAI_COST_API_KEY成本 API 专用密钥仅限 ORG-ADMIN推理密钥会收到 401/403。模板注释特别说明故意不命名为ANTHROPIC_API_KEY/OPENAI_API_KEY因为部署契约会从 admin 服务中剥离这两个名字。ADMIN_PLATFORM_COST_SHARES_JSON桌面/移动端成本分摊比例来自omi-cost-analysis用量加权报告结构为{llm:{desktop:..,mobile:..},core:{...},asOf:YYYY-MM-DD,method:..}。五、鉴权与权限模型5.1 生产环境鉴权链路正常运营中浏览器使用 Firebase Google 或邮箱登录。鉴权遵循双重校验原则客户端登录后要求当前用户 UID 存在于 Firestore 的adminData/{uid}文档中否则视为非管理员服务端强校验每个受保护 Route Handler 通过 Firebase Admin SDK 验证 ID Token不完全信任客户端检查结果。核心逻辑在 lib/auth.tsconst authorization request.headers.get(Authorization); if (DEV_BYPASS_ENABLED authorization Bearer ${DEV_BYPASS_TOKEN}) { return { uid: DEV_BYPASS_UID }; } // 正常路径验证 Firebase ID Token adminData/{uid} 存在性 const decodedToken await verifyFirebaseToken(token); const adminDoc await db.collection(adminData).doc(decodedToken.uid).get(); if (!adminDoc.exists) { return NextResponse.json({ error: Forbidden: Not an admin }, { status: 403 }); }失败时路由返回标准的 401令牌缺失/无效或 403非管理员响应。5.2 本地开发的权限矩阵README 按工作类型给出清晰的权限分档工作类型需要的前提条件纯 UI 工作启用开发绕过即可无需云端、Firebase 或厂商访问权限真实登录测试非生产项目中的 Firebase Authentication 用户 匹配的adminData/{uid}文档数据驱动页面能读取非生产 Firestore 项目的服务账号 被测页面对应的服务凭证本地 Omi API 联调本地后端ADMIN_KEY禁止申请或使用生产密钥通过 GitHub Actions 部署目标部署分支的合并/推送权限 目标 GitHub Environment 的审批需要权限的是工作流的部署身份而非开发者工作站需具备 Artifact Registry、Cloud Run 与 Cloud Run 运行时密钥的访问权若直接走 GCP 部署还需等价的 Cloud Run、Artifact Registry、服务账号模拟与 Secret Manager 权限六、提交前自检与 CI 校验6.1 本地检查命令README 要求开 PR 前执行npm run check npm run build从 package.json 的 scripts 可以看到check实际是三个检查的串联npm run lintESLintnpm run typechecktsc --noEmitnpm testVitest 单元测试。编写或修改测试时用npm run test:watch6.2 测试资产分布仓库为后台沉淀了较完整的测试体系可作为编写新测试的参照路由测试app/api/tests/route-param-encoding.test.ts、app/api/omi/team-members/tests/route.test.ts页面测试app/(protected)/dashboard/team/tests/page.test.tsx/dashboard/team/tests/page.test.tsx)核心逻辑测试web/admin/lib/__tests__/下覆盖鉴权、Stripe 订阅、统计指标诚实性stats-honesty-routes、stats-staleness-honesty、profitability-honesty、PostHog 行数限制、平台范围路由platform-scope、TV 模式等数十个用例。其中多个*-honesty测试说明该项目对后台统计数据的真实性有自动化约束很值得阅读学习。6.3 GitHub 侧检查GitHub 的 web check 会在web/admin/有改动时运行与本地相同的三项检查ESLint、TypeScript、Vitest随后执行生产构建。七、交付路径GitHub Actions → Docker → Cloud Run7.1 部署工作流.github/workflows/gcp_admin.yml 负责部署推送至main或development分支且包含web/admin/改动时触发。流程要点从本目录构建 Docker 镜像将公开的NEXT_PUBLIC_*值烘焙进镜像服务端密钥在 Cloud Run运行时注入不写入镜像将 100% 流量切换到新版本 revision。7.2 Dockerfile 中的密钥治理佐证Dockerfile 从构建层面印证了 README 的密钥边界设计多阶段构建deps安装依赖→builder构建→runner运行最终阶段使用非 root 的nextjs用户构建阶段通过 ARG 接收 9 个NEXT_PUBLIC_*变量OMI_REQUIRED_PUBLIC_BUILD_INPUTS并且构建前逐一校验这些变量非空缺失即失败服务端密钥明确不通过 build-arg 传递注释写着 Server-side secrets are injected at runtime via Cloud Run Secret Manager — no need to pass them as build-args运行时阶段同样强调密钥不烘焙进镜像NOT baked into the Docker image (more secure)采用 Next.js standalone 输出output: standalone配合.next/standalone与.next/static拷贝缩小镜像体积。7.3 已知缺口与后续方向README 明确列出当前尚未具备的能力没有 PR 预览部署、本地 Firebase emulator、预置的种子管理数据也没有浏览器端到端测试。这些是本地 UI 后端联调循环进入常规使用后值得优先投入的方向。对于想要贡献的开发者这是一个明确的切入点。八、开发注意事项速查客户端一律使用hooks/useAuthToken.ts发起网络请求禁止直接调用getIdToken()、自行构造鉴权头或读取 Firestore订阅类指标一律使用 lib/stripe-subscriptions.ts禁止按 price ID 遍历订阅数据获取契约、SWR 部分失败与订阅范围等更细的约定见 docs/data-contracts.md/dashboard通过grafana/嵌入 UID 为omi-tv的看板详见 grafana/README.mdTV 轮播分享链接走/dashboard/tv-links管理员→/tv/view/token免登录约定见 docs/tv-mode.md。结语Omi Admin Dashboard 是一个客户端轻、服务端重的典型 Next.js 内部后台浏览器只负责展示与登录一切敏感读取与写操作都收敛在受verifyAdmin保护的 Route Handler 中。从NEXT_PUBLIC_DEV_BYPASS_AUTH的本地开发捷径到 FirebaseadminData/{uid}双重校验再到 Cloud Run 运行时注入密钥与构建期强制校验NEXT_PUBLIC_*非空的部署契约整条链路的设计始终围绕服务端密钥不落浏览器、生产凭证不落本地这一安全基线。理解了这份 README 与配套源码你就能在本地快速迭代 UI、安全地对联后端并为后台补齐 PR 预览、Firebase emulator 与 E2E 测试等下一个里程碑。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考