Вы сделали приложение с поиском событий и избранным. Пока посетитель работает в одном браузере, список избранного можно хранить в localStorage. Но после входа с другого устройства эти данные уже не появятся. Понадобится учётная запись, чтобы связывать сохранённые события с конкретным человеком.
Supabase позволяет добавить авторизацию, базу данных и хранение пользовательских записей без разработки отдельного сервера авторизации. Разберём вход через email и то, как он связан с защитой данных.
Что делает Supabase Auth
При обычном входе приложение должно узнать пользователя, проверить его данные и поддерживать сессию. Supabase Auth берёт на себя эту часть работы. Для первого знакомства удобно выбрать вход по ссылке из письма, Magic Link. Пользователь указывает email, получает письмо и переходит по ссылке. После завершения входа приложение узнаёт его идентификатор.
Пароль в таком сценарии не нужен. Но авторизация не сводится к отправке письма. Нужно ещё правильно обрабатывать сессию и проверять, к каким записям пользователь имеет доступ.
Подключаем Supabase к Next.js
Создайте проект в Supabase. В его настройках доступны адрес проекта и публичный ключ для клиентского подключения. Секретные серверные ключи в браузер передавать нельзя.
Для Next.js App Router лучше начать с официального шаблона, в котором уже подготовлены TypeScript, cookie-based авторизация и серверный клиент Supabase.
npx create-next-app@latest my-app -e with-supabase
В .env.local добавьте значения своего проекта.
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-key
Публичный ключ предназначен для работы клиентской библиотеки. Он не заменяет проверку прав доступа к данным. В шаблоне уже есть маршруты входа и необходимые вспомогательные функции. Это позволяет сначала разобраться в поведении авторизации, а не собирать всю инфраструктуру с нуля.
Отправляем ссылку для входа
Посмотрим на основной вызов, который отправляет письмо пользователю. В примере supabase уже созданный клиент библиотеки.
const { error } = await supabase.auth.signInWithOtp({
email: "reader@example.com",
});
if (error) {
console.error(error.message);
}
Название signInWithOtp может сбить с толку. Для email Supabase по умолчанию использует Magic Link, если выбран соответствующий шаблон письма.
Перед запуском настройте адрес сайта и разрешённые адреса возврата в Supabase. Иначе пользователь может получить письмо, но не завершить вход на нужной странице. Для App Router также нужен обработчик завершения авторизации. В официальном шаблоне эта часть подготовлена. После перехода по ссылке появляется пользовательская сессия. Теперь можно показывать личные разделы и обращаться к данным от имени вошедшего пользователя.
Как получить текущего пользователя
Для страницы личного кабинета понадобится узнать, кто выполнил вход.
const {
data: { user },
error,
} = await supabase.auth.getUser();
if (error || !user) {
// Пользователь не вошёл или сессию не удалось проверить.
}
getUser() обращается к серверу авторизации Supabase. Для серверных страниц Next.js используется серверный клиент из настроенного шаблона, а не случайно созданный браузерный клиент.
После успешной проверки доступен user.id. Этот идентификатор можно использовать для связи записей с владельцем. Но наличие user.id ещё не означает, что приложение вправе показать любую запись из базы.
Почему одной авторизации недостаточно
Представим таблицу избранных событий. В ней есть user_id и event_id. Разработчик научился получать текущего пользователя, но забыл настроить ограничения на чтение таблицы. В результате один пользователь может получить записи другого, если запрос к базе не проверяет владельца. В Supabase для этого применяется Row Level Security, сокращённо RLS. Политики определяют, какие строки разрешено читать или изменять.
Например, правило для чтения собственных записей может выглядеть так.
create policy "Read own favorites"
on public.favorites
for select
to authenticated
using ((select auth.uid()) = user_id);
Эта политика предполагает, что таблица favorites уже создана, содержит столбец user_id, а RLS включён. Она разрешает вошедшему пользователю читать только строки со своим идентификатором. Для создания и удаления избранного понадобятся отдельные политики.
Здесь разделяются две задачи. Supabase Auth отвечает на вопрос, кто вошёл. RLS определяет, какие данные ему доступны. Одна настройка не заменяет другую.
От локального избранного к облачному
После подключения авторизации можно развивать привычную кнопку «В избранное». Гость сохраняет события локально. Пользователь, вошедший в аккаунт, получает список из базы Supabase и видит его на другом устройстве.
Добавляется ещё один сценарий. Человек сначала сохранил несколько событий без регистрации, а потом вошёл в аккаунт. Приложение должно решить, как перенести локальные записи в облако, исключить повторы и сохранить актуальное состояние интерфейса.
В курсовом проекте EventMap эта задача встроена в приложение для поиска событий. Там используются локализованные маршруты, внешний API, авторизация и облачное избранное.
Курс «Next.js III: SEO, i18n 2026» проходит путь от публичных страниц до Supabase Auth, RLS и пользовательских данных. Авторизация здесь становится частью работающего приложения, а не отдельной формой входа.
Для первого шага достаточно настроить Magic Link и проверить, что приложение получает пользователя после перехода из письма. Следующий шаг ограничить доступ к его данным и связать с аккаунтом конкретную функцию продукта.