Как построить расширение Chrome, делящее бэкенд с вашим SaaS?
Не строя второй бэкенд. MV3-расширение не может опираться на HttpOnly-cookie, поэтому авторизуйтесь воркспейс-ключами API: расширение вызывает версионированный REST API приложения (/api/v1) ограниченным ключом, привязанным ровно к одному воркспейсу, переиспользуя ту же модель авторизации, тот же тенант-скоупинг и ту же базу Postgres, что и веб-приложение. MV3-скаффолд supastack — попап, страница настроек, фоновый воркер, манифест минимальных прав — подключён именно так.
Ловушка: незаметно построить второй бэкенд
Обычная история: вашему SaaS нужно расширение-компаньон — захватывать страницы, клипать контент, аннотировать веб. Через полгода вы поддерживаете две системы авторизации (cookie для веба, самоделка для расширения), параллельный API, который расширение реально может вызывать, и слой синхронизации, выравнивающий два хранилища данных, которые должны были быть одним.
Ничего из этого не нужно. Расширение — просто ещё один клиент вашего существующего продукта: ему нужна учётка, которую оно может хранить, и API, рассчитанный на программный доступ. Ошибка — тянуться к новому бэкенду вместо того, чтобы использовать воркспейс-ключи API и версионированную REST-поверхность, которые у серьёзного SaaS уже есть.
Что Manifest V3 реально разрешает
MV3 заменил фоновые страницы короткоживущими сервис-воркерами и гонит расширения к минимальным правам. Практически: нельзя полагаться на постоянное состояние в памяти; не стоит выскребать cookie для переиспользования сессий (HttpOnly-cookie всё равно недосягаемы); и каждое хост-разрешение — вопрос при ревью веб-стора.
Чистый ответ — то, что платформа уже даёт: ограниченная учётка в chrome.storage.local и HTTPS-вызовы на origin вашего приложения, запрошенные как опциональные хост-разрешения при настройке, а не при установке.
MV3-скаффолд supastack: что уже подключено
apps/extension в supastack — намеренно маленький, безфреймворковый компаньон на Manifest V3 «сохранить страницу в воркспейс», показывающий весь паттерн от начала до конца. Он сохраняет заголовок, URL и выделенный текст активной вкладки как контент-запись воркспейса через версионированный REST API POST /api/v1/content-entries.
Авторизация — воркспейс-ключ API (sk_…), созданный в Settings → Developers: ключ привязан ровно к одному воркспейсу, поэтому сама привязка и есть выбор воркспейса — писать куда-то ещё он не сможет. Страница настроек сохраняет URL приложения и ключ в chrome.storage.local, запрашивает доступ только к этому origin и проверяет связь через 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 | Хранить URL приложения, ключ API и кэш воркспейса |
| optional_host_permissions | Origin приложения запрашивается при настройке — ноль доступа к сайтам при установке |
От скаффолда к компаньону вашего продукта
Ребрендинг — это смена имени в manifest.json; расширение — интересная часть, и она остаётся в том же паттерне: новые типы захвата вызывают новые эндпоинты /api/v1 тем же ключом, а типизированный @supastack/api-sdk, сгенерированный из OpenAPI-документа приложения, держит формы запросов честными.
Поскольку расширение читает и пишет через тот же тенант-скопированный API, что и любой другой клиент, сохранённые страницы попадают в те же строки Postgres, которые перечисляет веб-дашборд — одна база, одна модель авторизации, скоупинг workspaceId в ровно одном месте. Никакого второго бэкенда, синхронизации и дрейфа. Сравните тарифы на странице цен.
| Подход «свой второй бэкенд» | MV3-скаффолд supastack | |
|---|---|---|
| Авторизация | Самодельная токен-система рядом с cookie | Воркспейс-ключи API — та же модель авторизации, что у веба |
| API | Новые эндпоинты, придуманные для расширения | Версионированный /api/v1 + типизированный SDK из OpenAPI |
| Данные | Второе хранилище + логика синхронизации | Те же строки Postgres, скоуп воркспейса |
| Разрешения | Широкий доступ ради удобства | Манифест минимальных прав, дружелюбный к ревью |
FAQ: SaaS + расширение Chrome на одном бэкенде
Вопросы разработчиков перед выпуском расширения-компаньона:
- Почему ключ API а не сессионный cookie пользователя?, HttpOnly-cookie по дизайну невидимы для JS расширения, а сервис-воркеры MV3 короткоживущие — ограниченный ключ
sk_…вchrome.storage.localперсистентен, отзываем и привязан к одному воркспейсу, так что писать за его пределы не сможет. - Работает ли расширение в Firefox?, MV3 поддерживает ту же поверхность; код использует шим пространства имён
browser ?? chromeи разрабатывается Chromium-first — Firefox это порт, а не переписывание. - Готово ли оно к стору из коробки?, Это скаффолд продакшн-паттернов, а не сабмишн в стор — вы переименуете манифест, добавите свою логику захвата и напишете текст листинга. Сложная часть (авторизация, API, тенант-скоупинг) уже сделана.
- В какой тариф входит расширение?, Full Bundle за $299 поставляет все пять поверхностей — два веб-движка, Expo, Tauri и скаффолд расширения — в одном репо.