Технологии

Что такое RLS-политики в Supabase и как их настроить

9 минАктуально на 21 июля 2026

RLS-политики в Supabase

Ты уже собрал «Змейку» и даже добавил таблицу рекордов в Supabase. Теперь хочешь, чтобы каждый игрок видел общий топ, но при этом никто не мог подправить чужой результат или удалить всю таблицу одной кнопкой. Именно для этого в Supabase придуман Row Level Security — безопасность на уровне строк. Разберём, что это такое, почему без него нельзя запускать приложение в прод, и как настроить два самых нужных правила: читать всем, писать только себе.

Содержание
  1. Что такое RLS простыми словами
  2. Зачем RLS нужен в «Змейке»
  3. Как работают политики
  4. Как настроить RLS шаг за шагом
  5. Частые ошибки новичков
  6. Практическая проверка
  7. Заключение
  8. Источники

Что такое RLS простыми словами

RLS расшифровывается как Row Level Security — «безопасность на уровне строк». Обычно база данных похожа на таблицу Excel: если у тебя есть доступ к файлу, ты видишь и редактируешь все ячейки. Supabase с включённым RLS работает иначе: каждая строка таблицы сама решает, показывать себя текущему пользователю или нет, и разрешать ли ему что-то менять.

Представь школьный журнал. Без RLS ученик, вошедший в кабинет, может видеть все оценки и переписывать чужие. С RLS ученик открывает журнал и видит только свою страницу: свои оценки и замечания. Учитель видит все страницы. Завуч может редактировать всё. Один и тот же журнал, но содержимое зависит от того, кто спрашивает.

В Supabase «кто спрашивает» определяется через аутентификацию. Когда пользователь входит в приложение, Supabase Auth выдаёт ему уникальный идентификатор — обычно это UUID в поле auth.uid(). Политики RLS сравнивают этот идентификатор со значениями в таблице и решают: пропускать запрос или отказывать.

💡

Главная мысль: RLS — это не фильтр в коде приложения, а правила внутри самой базы данных. Даже если кто-то напрямую обратится к таблице через API, база не отдаст ему лишнего.

Зачем RLS нужен в «Змейке»

В модуле 5 учебный проект выходит за пределы локального браузера. Рекорды игроков хранятся в облачной таблице Supabase, а приложение читает и пишет туда через JavaScript. Без защиты любой, у кого есть публичный URL проекта и ключ, может:

  • прочитать всю таблицу, включая чужие email и результаты;
  • изменить чужой рекорд;
  • удалить все строки одним запросом;
  • добавить фейковые результаты.

Конечно, фронтенд может скрыть кнопки редактирования, но это не защита. Фронтенд — это код в браузере пользователя, его можно изменить, обойти или вообще проигнорировать, обратившись к API напрямую. Настоящая защита должна стоять в базе данных, потому что базу нельзя просто взломать через «Инспектор» в браузере.

Supabase по умолчанию блокирует доступ к таблице, если включить RLS, но не добавить политик. Это безопасное поведение: лучше сначала всё закрыть, а потом открыть только нужное, чем оставить дверь нараспашку.

Как работают политики

Политика RLS — это SQL-выражение, которое проверяется при каждом запросе. Она отвечает на два вопроса: какая операция разрешена и при каком условии. В Supabase политики бывают для операций SELECT, INSERT, UPDATE, DELETE и ALL.

Для таблицы рекордов «Змейки» обычно нужны всего два правила:

Операция Кому разрешено Зачем
SELECT Всем пользователям, включая анонимных Чтобы видеть общий топ рекордов
INSERT Только авторизованным пользователям Чтобы добавлять свой результат
UPDATE Только владельцу строки Чтобы исправить свой рекорд, но не чужой
DELETE Только владельцу строки или администратору Чтобы удалить только свой результат

Простейшая политика «читать всем» выглядит так:

create policy "Рекорды видны всем"
on public.scores
for select
using (true);

Здесь using (true) означает: условие всегда истинно, поэтому любой запрос SELECT проходит. Это безопасно для чтения, потому что в таблице рекордов нет секретных данных — только никнейм и очки.

Политика «писать только себе» выглядит чуть сложнее:

create policy "Игроки добавляют только свои рекорды"
on public.scores
for insert
with check (auth.uid() = user_id);

Здесь auth.uid() — это идентификатор текущего пользователя, а user_id — колонка в таблице, в которой хранится владелец записи. Если пользователь попытается вставить строку с чужим user_id, база отклонит запрос.

Политика «редактировать только своё» использует USING для существующих строк:

create policy "Игроки редактируют только свои рекорды"
on public.scores
for update
using (auth.uid() = user_id);
⚠️

Важно: политики INSERT обычно проверяют WITH CHECK, а SELECT, UPDATE и DELETEUSING. Если перепутать, правило либо не сработает, либо откроет слишком много.

Как настроить RLS шаг за шагом

Конкретные названия кнопок в интерфейсе Supabase могут меняться, но логика всегда одна и та же.

Шаг 1. Включи RLS для таблицы

Открой таблицу в редакторе Supabase и найди переключатель Row Level Security. Включи его. После этого любой доступ к таблице извне будет заблокирован, пока ты не добавишь политики.

Шаг 2. Добавь политику для чтения

Создай политику SELECT с условием true, если данные публичные. Для рекордов «Змейки» это нормально: топ должен видеть каждый.

Шаг 3. Добавь политику для записи

Создай политику INSERT, которая проверяет, что user_id в новой строке равен auth.uid(). Так приложение сможет сохранять рекорд только от имени вошедшего игрока.

Шаг 4. Добавь политики для изменения и удаления

Если игрок должен иметь возможность обновить свой счёт или удалить старый результат, добавь UPDATE и DELETE с условием auth.uid() = user_id.

Шаг 5. Проверь через приложение

Войди в приложение под одним пользователем, сохрани рекорд, затем попробуй прочитать таблицу под другим аккаунтом. Второй пользователь должен видеть строку первого, но не иметь возможности её изменить. Если попытаться подделать user_id в запросе, база вернёт ошибку доступа.

Шаг 6. Не открывай всё подряд

Если для операции нет политики, Supabase по умолчанию её запрещает. Не добавляй политику ALL с условием true «на всякий случай» — это эквивалент отключения защиты.

Частые ошибки новичков

Ошибка 1. Полагаться только на интерфейс

Скрыть кнопку удаления в React — не значит защитить данные. Любой может открыть консоль браузера или отправить запрос к API вручную. Защита должна быть в базе.

Ошибка 2. Забыть про auth.uid()

Если в таблице нет колонки user_id, политика auth.uid() = user_id не сработает. Убедись, что при создании записи приложение записывает туда идентификатор текущего пользователя.

Ошибка 3. Использовать true для всех операций

Политика for all using (true) открывает таблицу полностью. Это удобно на этапе разработки, но опасно в продакшене. Всегда ограничивай запись и изменение владельцем.

Ошибка 4. Путать USING и WITH CHECK

USING проверяет существующие строки, WITH CHECK — новые или изменённые. Для INSERT и обновлённых значений используй WITH CHECK, иначе база не поймёт, какую строку проверять.

Ошибка 5. Тестировать только под одним пользователем

Политики проявляют себя именно при переключении пользователей. Создай второй тестовый аккаунт и проверь, что он видит только разрешённое.

Практическая проверка

После настройки политик пройди по этому короткому чек-листу:

  • RLS включён для таблицы рекордов.
  • Добавлена политика SELECT для публичного чтения.
  • Добавлена политика INSERT с проверкой auth.uid() = user_id.
  • Добавлены политики UPDATE и DELETE для владельца строки.
  • В приложении при сохранении рекорда в колонку user_id записывается auth.uid().
  • Под другим аккаунтом видны чужие рекорды, но изменить их нельзя.
  • Попытка подделать user_id в запросе отклоняется базой.

Если все пункты выполнены, общая таблица рекордов готова к публикации.

Заключение

Row Level Security — это способ сделать так, чтобы база данных сама решала, к каким строкам у кого есть доступ. Вместо того чтобы надеяться на скрытые кнопки в интерфейсе, ты прописываешь правила один раз и они работают на уровне данных.

Для «Змейки» в Supabase достаточно двух базовых принципов: читать могут все, а писать, менять и удалять — только владелец строки. Это позволяет показать общий топ без риска, что кто-то испортит чужой результат. Когда освоишь эти два паттерна, сложные сценарии с ролями и администраторами пойдут уже намного легче.

💡

Итог: включай RLS до первого публичного запуска, добавляй политики с auth.uid() и всегда проверяй поведение под разными пользователями. Безопасность в базе — это не бонус, а базовая часть любого приложения с общими данными.

Источники

  1. Supabase — «RLS Performance and Best Practices»: supabase.com
  2. Supabase — «Policies»: supabase.com

Читай дальше

Все статьи

Не просто статьи — тебя доведут до результата

В практикуме за 1999 ₽ рядом живая команда практикующих разработчиков и маркетологов: ведём по шагам до твоего работающего приложения. Не «ролики и сам разбирайся» — помогаем на каждом затыке.

Перейти к практикуму
Все статьи Ещё: технологии и архитектура