> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# 如何构建带 Chrome 插件（MV3）的 SaaS：与主站共享认证和 API

多数团队为浏览器插件另起一套后端。本文演示如何让 Manifest V3 伴侣插件通过工作区 API 密钥直连你现有的 SaaS——不重复做认证，不开第二个数据库。

_发布于 2026-11-07._
_更新于 2026-11-07._

> **如何构建一个与你的 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` 隔离只在同一个地方强制。没有第二后端，没有同步，没有漂移。各档位见 [定价页](https://supastack.dev/#pricing)。

|  | 自建第二后端的做法 | 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 与插件脚手架。
