Ты собрал «Змейку», и она уже запоминает лучший результат в браузере. Это здорово, но только для тебя одного: если друг зайдёт со своего телефона, он увидит свой рекорд, а не твой. Чтобы соревноваться, нужно хранить счёта в одном общем месте — в базе данных в интернете. В курсе мы используем Supabase: это облачная база данных с готовым API, к которой браузер обращается напрямую. Дальше — как устроена общая таблица рекордов, как туда попадают результаты и как не дать читерам забить весь топ фейковыми баллами.
Содержание
Почему localStorage не подходит для общего рейтинга
localStorage — это хранилище внутри браузера. Оно удобно для личных настроек: звук включён, выбран скин, последний лучший результат. Но у него два ограничения, которые мешают соревнованию.
Первое: данные лежат только на устройстве игрока. У ноутбука — одна копия, у телефона — другая, у друга — третья. Второе: любой, кто откроет консоль браузера, может подменить значение. Для личного рекорда это некритично, а для общей таблицы — смертельно: достаточно одного желающего написать себе миллион очков, и рейтинг потеряет смысл.
Поэтому общий рейтинг хранят на сервере. Браузер отправляет результат туда, сервер записывает его в базу, а при запросе отдаёт уже проверенные данные. Supabase берёт на себя серверную часть: ты описываешь структуру таблицы и правила доступа, а Supabase сам создаёт HTTP-API, через которое приложение читает и пишет данные.
Что такое Supabase простыми словами
Supabase — это платформа-обёртка над базой данных PostgreSQL. PostgreSQL — мощная открытая система управления базами данных, в которой данные хранятся в таблицах. Supabase добавляет к ней готовую авторизацию, авто-API и удобную панель управления.
Для новичка важно главное: вместо того чтобы писать собственный сервер на Node.js или Python, ты можешь создать таблицу в Supabase и сразу обращаться к ней из JavaScript-кода игры. Supabase превращает запросы к базе в обычные HTTP-вызовы: «дай топ-10», «запиши новый результат». В проектах, созданных после 30 мая 2026, таблицу нужно сначала открыть для Data API через SQL-команду GRANT, иначе запросы получат ошибку доступа.
Таблица scores: что в ней хранится
Для таблицы рекордов обычно используют имя scores. Каждая строка в ней — это одна попытка одного игрока. Минимальный набор столбцов выглядит так:
| Столбец | Тип | Зачем нужен |
|---|---|---|
id |
уникальный идентификатор | Автоматический номер строки, чтобы не путать записи между собой. |
user_id |
идентификатор пользователя | Связь с аккаунтом: кто именно набрал очки. |
score |
число | Набранные очки. |
created_at |
дата и время | Когда была попытка. Пригодится для сортировки одинаковых результатов. |
Можно добавить и другие поля — например, nickname, если хочешь показывать имя игрока рядом со счётом, или level, если в игре есть уровни сложности. Но для начала хватит четырёх базовых.
Связь user_id с таблицей пользователей Supabase позволяет понять, кто автор записи. Если в игре есть авторизация, игрок входит под своим аккаунтом, и его user_id подставляется автоматически. Если авторизации пока нет, можно генерировать анонимный идентификатор, но тогда защита от накрутки сильно слабеет — об этом ниже.
Как результат попадает в таблицу
Когда игра заканчивается, код считает финальный результат и отправляет его в Supabase через API. В терминах баз данных это операция INSERT — вставка новой строки в таблицу.
Простая аналогия: таблица scores — это общая тетрадь, лежащая на столе в классе. Каждый ученик после игры подходит и записывает в неё свой результат. Чтобы записи не перемешались, в тетради заранее есть графы: кто, сколько, когда.
В коде это выглядит примерно так: «вставь в таблицу scores строку, где score равен 42, а user_id — текущий пользователь». Supabase возвращает подтверждение, и игра может показать игроку, что результат сохранён.
Отправлять результат стоит только после реально завершённой игры. Если отправлять счёт каждую секунду или по кнопке «Сохранить», появляются лишние возможности для манипуляций.
Как получить топ-10
Топ-10 — это обычный запрос на чтение. В терминах баз данных он звучит так: «выбрать из таблицы scores, отсортировать по убыванию поля score и взять первые 10 строк».
В SQL — языке запросов к базам данных — это выглядит так:
SELECT * FROM scores
ORDER BY score DESC, created_at ASC
LIMIT 10;
Здесь ORDER BY score DESC означает «сначала самые большие значения score». created_at ASC нужен, чтобы при равных очках раньше шёл тот, кто набрал результат первым. LIMIT 10 отсекает всё лишнее.
Через Supabase-клиент в JavaScript тот же запрос пишется почти на русском языке: «из таблицы scores выбери все столбцы, отсортируй по score вниз, по created_at вверх, верни 10 записей». Результат приходит массивом объектов, которые можно сразу отрисовать в таблице на экране.
Защита от накрутки через RLS
RLS расшифровывается как Row Level Security — «безопасность на уровне строк». Это механизм PostgreSQL, который проверяет каждую операцию с таблицей и решает, разрешена она или нет. Проще говоря, RLS — это правила, написанные прямо в базе данных, которые нельзя обойти из браузера.
Представь ту же школьную тетрадь, но с учителем у стола. Каждый ученик может только:
- положить в тетрадь свою новую запись;
- смотреть общий список;
- не может стереть чужую запись;
- не может исправить свой старый результат на больший.
Пример политик RLS для таблицы scores:
- Чтение разрешено всем. Любой посетитель может посмотреть топ-10.
- Вставка разрешена только авторизованным пользователям. Игрок может добавить запись только от своего имени.
- Обновление и удаление запрещены. Никто не может подменить или стереть чужой результат.
Благодаря этому даже если кто-то откроет консоль браузера и попытается отправить запрос «поставь мне 999 999 очков от имени другого игрока», база откажет: RLS проверит user_id и скажет «нет».
Конечно, RLS не защищает от всех видов читерства. Если игрок авторизован, он всё ещё может написать бота, который будет играть за него, или взломать клиентскую часть игры, отправляя результат без реальной игры. Но это уже другой уровень защиты, который требует проверки игрового процесса на сервере. Для учебного проекта и первых шагов RLS — надёжный минимум.
Практический блок: как применить
Если ты проходишь модуль 5 курса, у тебя уже есть «Змейка» с localStorage-рекордом. Вот концептуальный план, как добавить общую таблицу:
- Создай в Supabase таблицу
scoresс нужными столбцами:id,user_id,score,created_at. Если проект создан после 30 мая 2026, добавьGRANTдля ролейanonиauthenticated, иначе Data API не увидит таблицу. - Включи RLS и добавь политики: чтение для всех, вставка только для авторизованных от своего имени, изменение и удаление запрещены.
- Подключи Supabase-клиент в код игры: передай ему URL проекта и публичный ключ.
- После окончания игры отправляй результат в таблицу
scoresчерез операцию вставки. - При открытии таблицы рекордов запрашивай топ-10 с сортировкой по
scoreубыванием. - Проверь защиту: попробуй из консоли отправить чужой
user_idили подменитьscore— запрос должен быть отклонён.
Точные названия кнопок и пунктов меню Supabase меняются со временем, поэтому ориентируйся на актуальную документацию: supabase.com/docs.
Что делать, если результат не сохранился
Самые частые причины проблем при работе с Supabase:
- RLS включён, но политик нет. Тогда любой запрос на вставку или чтение отклоняется. Проверь, что политики созданы и включены.
- Таблица не открыта для Data API. В новых проектах Supabase требует явных прав
GRANTна чтение и запись. Ошибка выглядит какcode: 42501, permission denied for table scores. - Неверный ключ или URL. Браузер не может подключиться к проекту. Перепроверь значения в коде.
- Пользователь не авторизован, а вставка разрешена только авторизованным. Добавь вход через email или анонимную авторизацию.
- Тип данных не совпадает. Например, в
scoreпытаешься записать текст вместо числа.
Если что-то не работает, открой консоль браузера — Supabase обычно пишет туда понятные ошибки.
Заключение + чек-лист
Общая таблица рекордов превращает одиночную игру в соревнование. Вместо локального хранилища браузера ты используешь облачную базу Supabase, куда каждый игрок отправляет свой результат, а все остальные видят топ-10. Главное — не забыть про RLS: без правильных политик таблица станет лёгкой мишенью для накрутки.
Чек-лист «Общая таблица рекордов готова»
- Создана таблица
scoresс полямиid,user_id,score,created_at. - Включён RLS.
- Добавлена политика: чтение топа разрешено всем.
- Добавлена политика: вставка только авторизованным и только от своего имени.
- Запрещены обновление и удаление строк.
- В коде игры подключён Supabase-клиент.
- После завершения игры результат отправляется в таблицу.
- На экране рекордов запрашивается и отображается топ-10.
- Проведена проверка: подмена
user_idилиscoreиз консоли отклоняется.
Главная мысль: база данных — это не магия, а общая тетрадь с правилами. Supabase даёт готовые правила доступа, а твоя задача — правильно их настроить, чтобы честные игроки могли соревноваться, а жулики — нет.
Читай дальше
Все статьиНе просто статьи — тебя доведут до результата
В практикуме за 1999 ₽ рядом живая команда практикующих разработчиков и маркетологов: ведём по шагам до твоего работающего приложения. Не «ролики и сам разбирайся» — помогаем на каждом затыке.
Перейти к практикуму