Авторизация и RLS в Supabase: роли и доступ
Как устроена авторизация, что такое политики доступа на уровне строк, какие политики нужны в типовом проекте и где чаще всего ломаются MVP.
Все статьи гида Supabase · 7
Это главная статья гида: вся модель безопасности Supabase держится на правилах доступа к строкам. Проект, где они настроены неверно, выглядит рабочим и таковым не является.
Как устроена авторизация
Пользователь регистрируется или входит, сервис выдаёт ему токен. Приложение отправляет этот токен с каждым запросом, а база по нему понимает, кто именно спрашивает.
Ключевая деталь, которую надо понять сразу: запросы идут в базу напрямую из приложения. Промежуточного слоя, который проверял бы права, нет - его роль выполняют правила в самой базе.
Отсюда два ключа:
- Публичный ключ используется в приложении и по определению доступен любому пользователю. Он не даёт никаких прав сам по себе: права определяются токеном и политиками.
- Служебный ключ обходит все правила. Он должен жить только на сервере и никогда не попадать в клиентский код. Утечка такого ключа означает полный доступ ко всем данным.
Что такое RLS
Row Level Security - механизм PostgreSQL, ограничивающий доступ на уровне отдельных строк.
Вместо проверки в коде приложения вы описываете правило один раз в базе: «пользователь видит только те заказы, где идентификатор владельца совпадает с его собственным». Правило действует для любого запроса, откуда бы он ни пришёл.
Два обязательных условия, и оба пропускают:
- Построчный доступ включён для таблицы. Без этого таблица открыта всем.
- Написаны политики. Таблица с включённым RLS и без политик закрыта полностью, что честнее, но тоже неверно.
Типовые политики
Набор, покрывающий большинство проектов:
Своё видно, чужое нет. Пользователь читает и меняет строки, где он владелец.
Общее чтение, ограниченная запись. Каталог виден всем, менять может только владелец записи.
Разделение чтения и записи. Отдельные политики на чтение, вставку, обновление и удаление. Частая ошибка - одна политика на всё: пользователь получает право менять то, что должен был только читать.
Роли. Признак роли хранится в базе, а не в токене, который пользователь может подделать. Политика проверяет роль запросом к таблице пользователей.
Мягкое удаление вместо настоящего. Запись помечается удалённой, а политика скрывает помеченные. Дешевле, чем восстанавливать удалённое.
Где чаще всего ломаются MVP
Пять ошибок в порядке частоты:
1. RLS не включён. Таблица создана, данные добавлены, всё работает. Работает потому, что доступ открыт всем, у кого есть публичный ключ. Это самая частая и самая дорогая ошибка.
2. Служебный ключ в клиентском коде. Обходит все правила. Ключ в коде фронтенда виден всем.
3. Проверка прав только в интерфейсе. Кнопка удаления скрыта, а запрос на удаление проходит: пользователь может отправить его напрямую.
4. Слишком широкая политика. Разрешение на чтение всей таблицы «на время отладки», которое остаётся навсегда.
5. Роль из токена. Токен формируется на клиенте и не является доказательством. Роль проверяется по данным в базе.
Как проверить, что всё закрыто
Проверять надо специально, а не по факту работы приложения:
- Список таблиц с выключенным RLS. Одним запросом. Каждая такая таблица - потенциальная утечка.
- Запрос от имени другого пользователя. Заведите второй аккаунт и попробуйте прочитать чужие данные напрямую, минуя интерфейс.
- Запрос без токена вовсе. Что видно анонимному пользователю с публичным ключом.
- Попытка изменения чужой строки.
- Поиск служебного ключа в клиентском коде и в репозитории.
Практическое правило: включайте RLS сразу при создании таблицы, до того, как положите в неё данные. Возвращаться к этому потом означает проверять каждую таблицу вручную, а какую-то вы пропустите.
Логика, которую нельзя отдавать клиенту, живёт в edge-функциях. Общая картина - гид по Supabase.
Вопросы и ответы
Что такое RLS в Supabase?
Механизм PostgreSQL, ограничивающий доступ на уровне отдельных строк таблицы. Вместо проверки прав в коде приложения правило описывается один раз в базе, и оно действует для любого запроса, откуда бы он ни пришёл. Это и есть основа модели безопасности здесь.
Почему в Supabase видны чужие данные?
Почти всегда потому, что для таблицы не включён построчный доступ или не написаны политики. Таблица без включённого RLS доступна всем, у кого есть публичный ключ, а он по определению есть у любого пользователя приложения. Это ошибка номер один в проектах на Supabase.
Можно ли доверять проверкам на клиенте?
Нет. Всё, что выполняется в браузере, находится под контролем пользователя: запрос можно отправить напрямую, минуя ваш интерфейс. Клиентские проверки нужны для удобства, а безопасность обеспечивается только правилами в базе.
Ещё по теме
- Supabase: что это и с чего начатьГид
- Edge-функции Supabase: логика без своего сервераКогда нужны серверные функции, какие у них ограничения, как работать с секретами и как устроены деплой, логи и отладка.
- Supabase против Firebase: что выбрать под MVPЧем отличаются модели данных, как ведёт себя цена на росте, насколько сильна привязка к поставщику и как выбрать под конкретный проект.
- Self-hosted Supabase: развернуть у себяЗачем поднимать Supabase на своём сервере, что входит в стек, что обязательно бэкапить, как проходят обновления и чего не будет по сравнению с облаком.
Сделаю под ключ
Соберу MVP на Supabase
Авторизация, база с RLS, хранилище, функции и оплата, настроенные правильно с первого раза.
от 1 500 $ · 1-2 недели