如何构建一个与你的 SaaS 共享后端的 Chrome 插件?
关键在于不建第二个后端。MV3 插件无法依赖 HttpOnly Cookie,所以改用工作区 API 密钥认证:插件带着绑定单一工作区的受限密钥调用应用版本化 REST API(/api/v1),复用与 Web 应用相同的认证模型、租户隔离和 Postgres 数据库。supastack 自带的 MV3 脚手架——弹窗、选项页、后台 worker、最小权限清单——正是按这套方式接线的。
陷阱:不知不觉建了第二个后端
常见剧情是:你的 SaaS 需要一个伴侣插件来采集网页、剪藏内容或标注页面。六个月后,你维护着两套认证系统(Web 用 Cookie,插件用某种手搓方案)、一套插件真正调得动的平行 API,外加一个在两个本应是同一个的数据存储之间对齐的同步层。
这些全都没必要。插件只是你现有产品的一个客户端——它需要一个拿得住的凭证、一个为程序化访问设计的 API,仅此而已。错误在于伸手去建新后端,而不是用一个严肃 SaaS 早已具备的工作区 API 密钥和版本化 REST 端面。
Manifest V3 实际允许你做什么
MV3 用短暂存活的 Service Worker 取代了后台页面,并把插件推向最小权限模型。实操上:不能依赖常驻内存状态;不该去抠 Cookie 做会话复用(HttpOnly Cookie 反正也摸不到);每一项主机权限都是应用商店审核时要回答的问题。
干净的答案正是平台已经给你的:一把放在 chrome.storage.local 里的受限凭证,加上指向你应用域名的 HTTPS 调用——在安装后的设置环节以可选主机权限申请,而不是安装时。
supastack 的 MV3 脚手架:已经接好线的部分
supastack 的 apps/extension 是一个刻意保持小巧、零框架的 Manifest V3 伴侣——「保存页面到工作区」——端到端演示了整套模式。它通过版本化 REST API POST /api/v1/content-entries,把当前标签页的标题、URL 与选中文本存进一条工作区内容记录。
认证用的是在「设置 → 开发者」下创建的工作区 API 密钥(sk_…):密钥只绑定一个工作区,所以绑定本身就是工作区选择——密钥永远写不到别处。选项页把应用地址与密钥存进 chrome.storage.local,只为该域名申请访问权,并通过 GET /api/v1/workspaces/current 验证连通。
apps/extension/
manifest.json MV3: service worker, least-privilege permissions
src/
background.js context-menu save + badge feedback
popup.html/.js capture UI — title, URL, selection, note
options.html/.js app URL + workspace API key setup
lib/
api.mjs versioned /api/v1 client (key auth)
capture.mjs active-tab + selection capture
config.mjs chrome.storage.local persistence默认最小权限
脚手架只带这件工作真正需要的最小权限集——这对应用商店审核和用户信任都重要:
- 没有
tabs、没有<all_urls>、没有 cookies/webRequest/declarativeNetRequest——脚手架诚实地声明自己不需要什么。
| 权限 | 用途 |
|---|---|
| activeTab | 仅在调用时读取当前页的标题/URL |
| scripting | 读取被调用标签页内的选中文本 |
| contextMenus | 注册右键「保存」菜单项 |
| storage | 持久化应用地址、API 密钥与工作区缓存 |
| optional_host_permissions | 应用域名在设置时才申请,安装时零站点访问 |
从脚手架到你产品的伴侣插件
改品牌就是改 manifest.json 的名字;扩展功能才是有意思的部分,而且依然落在同一模式里——新的采集类型用同一把密钥调用新的 /api/v1 端点,由应用 OpenAPI 文档生成的类型化 @supastack/api-sdk 保证请求体不走样。
因为插件与其他客户端一样,通过同一套租户隔离的 API 读写,保存下来的页面落进 Web 控制台列出的同一批 Postgres 行——一个数据库、一套认证模型、workspaceId 隔离只在同一个地方强制。没有第二后端,没有同步,没有漂移。各档位见 定价页。
| 自建第二后端的做法 | supastack MV3 脚手架 | |
|---|---|---|
| 认证 | 在 Cookie 旁边手搓一套令牌体系 | 工作区 API 密钥——与 Web 同一认证模型 |
| API | 为插件新造一套端点 | 版本化 /api/v1 + OpenAPI 类型化 SDK |
| 数据 | 第二存储 + 同步逻辑 | 同一批 Postgres 行,工作区隔离 |
| 权限 | 图省事申请宽泛访问 | 最小权限清单,对审核友好 |
常见问题:SaaS + Chrome 插件共用一套后端
开发者在交付插件伴侣之前常问的问题:
- 为什么用 API 密钥而不是用户的会话 Cookie?, HttpOnly Cookie 在设计上就对插件 JS 不可见,而 MV3 Service Worker 生命短暂——
chrome.storage.local里一把受限的sk_…密钥持久、可吊销,且绑定单一工作区,永远跨不了租户。 - 插件在 Firefox 上能用吗?, MV3 支持同一套端面;代码使用
browser ?? chrome命名空间垫片且以 Chromium 优先开发,所以 Firefox 是移植而非重写。 - 开箱就能上商店吗?, 它是一个生产级模式的脚手架,不是商店提交件——你需要给清单改名、加自己的采集逻辑、写商店文案。最难的部分(认证、API、租户隔离)已经做完。
- 哪个档位包含插件?, $299 的 Full Bundle 在同一仓库交付全部五个端面——两个 Web 引擎、Expo、Tauri 与插件脚手架。