📱 Подписаться
IT и цифровая трансформация

Firebase, Supabase и BaaS: как мы к такому пришли и что там внутри

📰 Habr 👁️ 1 просмотров

MarkovM2 часа назад

Firebase, Supabase и BaaS: как мы к такому пришли и что там внутри

Время на прочтение7 минОхват и читатели3.4KБлог компании AmveraБазы данных*PostgreSQL*Искусственный интеллектВеб-разработка*ОбзорВсем привет!

Ранее мы разбирались с одним конкретным примером - Supabase: как его поставить, зачем он нужен, какие есть аналоги и почему вокруг него в последнее время так много шума.

Но, мне кажется, что сейчас будет правильно сделать шаг назад и поговорить не про конкретный сервис, а про весь BaaS (Backend-as-a-Service). Как мы уже узнали из прошлой статьи, Supabase не возник сам по себе, до него был Firebase, а до Firebase были обычные самописные API, куча настроек авторизации, хранения файлов, нотификаций с вебсокетами и остального.

В этой статье мы разберем, что такое BaaS, почему он вообще понадобился, чем Firebase отличается от Supabase, для каких приложений такой подход подходит, а где уже нужен собственный backend.

Как мы вообще пришли к BaaS

Если очень грубо, то классическое веб-приложение с минимум функций, требующих авторизацию, выглядело так: пользователь открывает сайт или приложение, приложение отправляет запрос на backend, backend проверяет пользователя, лезет в базу данных, что-то там считает, что-то сохраняет, а потом возвращает ответ обратно.

Вообще, это основная схема и сейчас, проблема немного в другом: почти в каждом MVP проекте backend начинает с одних и тех же, можно сказать душных, задач.

То есть:

• Нужно зарегистрировать пользователя,
• Нужно сделать вход по почте и паролю,
• Нужно хранить сессии и токены,
• Нужно дать пользователю возможность загрузить аватарку,
• Нужно сделать CRUD (Create, Read, Update, Delete) для каких-то данных,
• Нужно настроить роли доступа,
• и т.д., это можно продолжать бесконечно.И тут у одних умных людей возникла мысль: а что если типовой backend не писать каждый раз заново? И мысль действительно умная, ведь уже очень давно существует один из главных принципов программирования - DRY - Don’t Repeat Yourself! Зачем повторять в каждом проекте одно и то же, если можно создать набор готовых backend-сервисов, к которым можно подключать frontend.

Так и появился подход Backend-as-a-Service, или BaaS.

Если совсем коротко, то BaaS - это набор готовых backend-сервисов, к которым frontend или мобильное приложение подключаются через SDK или API.

А что с безопасностью?

Я думаю у многих читателей, кто только-только узнает о BaaS возник очень даже логичный вопрос: а как это? Получается, что прям в коде веб-приложения, который доступен абсолютно каждому пользователю, что открыл сайт, есть код подключения BaaS со всеми секретными токенами и бизнес-логикой?

Почти. Действительно, абсолютно каждый пользователь, что открыл сайт, может увидеть строку подключения того же Firebase, вместе с самым страшным: токеном.

Но, думаю было бы очень глупо, если бы этот токен был секретом. На самом деле это просто публичный идентификатор проекта в самом Firebase. Он нужен лишь для того, чтобы API Firebase знал, к какому проекту относить запросы с этого фронтенда.

Любой пользователь, конечно, может подменить этот токен и слать запросы в другой проект, вопрос в другом: а зачем? Конечно же, это ничего ему не даст.

В общем, с безопасностью все окей, никакие секретные токены в коде frontend’а не хранятся.

В чем разница между Firebase и Supabase?

Тут максимально кратко: Firebase - это сервис от Google, у которого каждый сервис - это что-то свое, но который не раскрывает свои исходники, а Supabase - это аналог, который собран на OpenSource компонентах, исходный код которого открыт для каждого пользователя. Естественно, на этом все отличия не заканчиваются, некоторые из них я опишу ниже.

А что именно входит в состав готовых backend-сервисов?

В основном, в состав готовых backend-сервисов входит то, что повторяется в проектах чаще всего:

• Авторизация;
• база данных;
• автоматический API;
• хранение файлов;
• получение обновлений в realtime (об этом чуть ниже подробнее будет);
• serverless-функции;
• нотификации;
• аналитика;
• и разные доп. инструменты для логов, мониторинга и прочего.То есть BaaS пытается закрыть не какую-то одну проблему, а целый слой backend-сервисов.

Давайте чуть подробнее для некоторых сервисов

Авторизация

Авторизация - это, наверное, второе, после базы данных, с чем сталкивается любое приложение, которое сложнее лендинга.

Пользователь должен зарегистрироваться, войти, восстановить пароль, подтвердить почту, может войти через Google/Github/Yandex/Apple. Все это довольно сложно, если писать самому.

И сложно не потому что работать долго, а потому что авторизация обязательно должна быть достаточно безопасной. Пароли обязательно должны хешироваться, должны возвращаться JWT или сессии, нужно защититься от перебора паролей, придумать и настроить роли.

Ну и конечно же это есть практически в любом BaaS. В Firebase для этого есть Firebase Authentication. В Supabase - Supabase Auth. В обоих случаях можно довольно быстро получить регистрацию, логин, OAuth и текущего пользователя.

То есть вместо того, чтобы писать отдельный сервис пользователей, вы делаете что-то типо:

const { data, error } = await supabase.auth.signInWithPassword({
email: 'почта пользователя',
password: 'пароль пользователя',
})или

import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'

const auth = getAuth()

const userCredential = await signInWithEmailAndPassword( auth, email, password )

const user = userCredential.user

База данных

В BaaS все довольно просто: база данных уже есть, SDK обычно есть, API тоже.

Но здесь, кстати, есть важное отличие между Firebase и Supabase.

Firebase уже давно живет в мире NoSQL. У него есть своя Realtime Database и Cloud Firestore. Это не обычная реляционная база данных с таблицами, связями и JOIN’ами, а документная модель данных.

Realtime Database хранит данные как одно большое JSON-дерево:

{
"users": {
"user_1": {
"name": "user1",
"email": "user1@users.com"
},
"user_2": {
"name": "user2",
"email": "user2@users.com"
}
},
"tasks": {
"task_1": {
"title": "Read article",
"userId": "user_1",
"isDone": false
},
"task_2": {
"title": "Write article",
"userId": "user_2",
"isDone": true
}
}
}То есть данные фактически лежат по путям. Например, можно обратиться к /users/user_1 и получить данные конкретного пользователя. Или к /tasks/task_1 и получить конкретную задачу.

А в Supabase все проще: там используется PostgreSQL и данные хранятся в привычном всем нам виде.

Realtime

Realtime - это очень важная часть BaaS.

Раньше, если нужно было обновлять данные без перезагрузки страницы, приходилось выбирать между polling, SSE, WebSocket, отдельным message брокером или realtime-сервисом.

Firebase изначально очень сильно выстрелил именно за счет realtime-подхода. Приложение “подписывается” на данные, и когда они меняются, клиенты получают обновления.

Это очень удобно для:

• чатов;
• онлайн-досок;
• статусов заказа;
• уведомлений внутри приложения;
• возможно даже совместного редактирования.Supabase, конечно, тоже умеет в realtime, но там это работает иначе. Так как в центре вообще всего находится PostgreSQL, realtime подписывается на изменения в базе и рассылает их клиентам.

Serverless-функции

Не всегда базовых вещей типа авторизации и базы данных достаточно, почти в каждом проекте есть своя бизнес-логика, которую ни в коем случае нельзя реализовывать в коде frontend’а.

Поэтому обычно в BaaS даютserver-less функции.

В Firebase это Cloud Functions, в Supabase - Edge Functions.

Выглядит это примерно так:

await fetch('/create-payment', { // очень частый сценарий
method: 'POST',
body: JSON.stringify({ plan: 'pro' })
})А эта функция на серверной стороне обращается к платежке, проверяет пользователя, создает платеж и возвращает результат.

А можно ли собрать свой BaaS стек?

После Firebase и Supabase возникает вопрос: а можно ли собрать подобное самому?

Не обязательно прям “свой Supabase”, так как Supabase - это не один сервис, а довольно огромная платформа. Там есть PostgreSQL, Auth, PostgREST, Realtime, Storage, Edge Functions, Studio, API Gateway и еще куча связующего кода.

Но если говорить не про полную копию, а что-то идейно похожее, то да.

Например, можно взять:

• PostgreSQL как основную базу данных
• RLS (Row Level Security) в PostgreSQL для ограничения доступа к строкам,
• PostgREST для автоматического RestAPI поверх PostgreSQL,
• Keycloak для авторизации и выдачи JWT,
• Отдельный backend для какой-то приватной бизнес-логики.Развернуть это все можно и самостоятельно, но мы воспользуемся готовым решением, где все можно сделать "одной кнопкой" . И заодно немного прорекламируем себя, надеюсь на ваше понимание.

В простом запуске нам поможет сервис Amvera. Это сервис для быстрого развертывания IT-приложений, особенность которого заключается в отсутствии необходимости самостоятельной настройки окружения. Здесь вы буквально за 10-15 минут сможете развернуть весь вышеописанный стек, лишь заполнив некоторые параметры компонентов.

Самое важное: для первого запуска вы можете использовать бонусный баланс в размере 111 рублей, доступный сразу после регистрации.

Как это может работать

Фактически схема будет такая:

На фронтенде пользователь логинится через Keycloak. После успешного входа frontend получает JWT токен. Потом frontend отправляет запрос PostgREST и передает этот JWT токен в заголовке Authorization.

PostgREST проверяет токен, принимает пользователя, определяет его роль (анонимную, если токен недейстивтельный, или авторизованную, если токен корректный) и идет в PostgreSQL. В самом PostgreSQL при этом необходимо настроить RLS, который будет отдавать только и только те строки из таблиц, которые принадлежат конкретному пользователю (в этом и будет заключаться вся безопасность на уровне строк).

Например, в PostgreSQL можно включить RLS для таблицы: alter table <название-таблицы> enable row level security;

А потом создать Policy, которая разрешит пользователю видеть только свои данные:

create policy "Users can read only own data" on <название-таблицы>
for select
using (
user_id = (
current_setting('request.jwt.claims', true)::jsonb ->> 'sub'
)::uuid
);Если дословно:

Создать политику с названием "Users can read only own data" для таблицы <название-таблицы> для SELECT, при этом user_id (название ячейки в таблице, значение - обязательно uuid для данной политики) должно быть равно UUID, полученному из jwt во входящем запросеИ если все настроить корректно, PostgREST вернет только те строки, которые принадлежат конкретному юзеру. Ровно то же самое можно сделать с DELETE, INSERT, UPDATE и реализовать базовый CRUD.

Развертывание сервисов

Как я говорил выше, развернуть каждый из сервисов можно в Amvera. Это займет не более 20-и минут.

PostgreSQL

PostgreSQL предоставляется как managed-сервис с бэкапами. После регистрации его можно развернуть с помощью кнопки “Создать базу данных” в разделе PostgreSQL.

Запускаем PostgreSQLПри создании вам понадобится лишь выбрать базовые настройки: название базы данных, юзера, пароли. Связать PostgreSQL с остальными проектами можно как по внутреннему доменному имени, так и по бесплатному внешнему.

PostgREST

Этот сервис предоставляется как преднастроенный. Для его создания выберите раздел “Преднастроенные сервисы”. При создании понадобится выбрать данные для подключения к PostgreSQL и название анонимной роли.

Выбираем преднастроенный сервисВыбираем PostgREST

Keycloak

Как и PostgREST, Keycloak можно развернуть в разделе “Преднастроенные сервисы”. Понадобится выбрать данные временного администратора Keycloak и данные для подключения PostgreSQL.

Выбираем KeycloackЗадаем необходимые переменные

Итог

BaaS появился не потому, что backend стал не нужен, он появился потому что в огромном количестве проектов повторяются одни и те же сценарии, которые можно не писать каждый раз заново.

В данной статье я рассказал об устройстве BaaS и о том, как можно создать свой BaaS достаточно поверхностно, но уже в следующей статье я разберу тему максимально подробно, показав на примере, как из open source компонентов собрать свое BaaS-решение.Теги:• baas
• backend as a service
• firebase
• supabase
• managed postgresql
• firebase realtime
• firebase auth
• supabase auth
• supabase self hosted
• supabase локальноХабы:• Блог компании Amvera
• Базы данных
• PostgreSQL
• Искусственный интеллект
• Веб-разработка

Получайте больше инсайтов о систематизации бизнеса

Подписывайтесь на Telegram-канал Business Operations — ежедневные материалы о бизнес-процессах, операционном управлении и повышении эффективности

💬 Подписаться на канал