Игра вроде Змейки готова — и теперь хочется, чтобы у каждого игрока был свой аккаунт: сохранялся рекорд, открывался магазин скинов, работала таблица лидеров. Значит, нужно научить приложение узнавать пользователя. Классический путь — попросить придумать пароль. Но пароли легко забыть, ещё легче украсть, а хранить их безопасно — отдельная наука. В курсе skillmake для входа используется код на почту: ты вводишь email, получаешь шестизначный код, вводишь его — и ты внутри. Разберёмся, как работает такая авторизация, что происходит с сессией, зачем нужны cookie и токены и почему от паролей можно отказаться.
Содержание
- Зачем отказываться от паролей в простом приложении
- OTP: одноразовый пароль на почту
- Что такое сессия
- Cookie: как браузер запоминает сессию
- Токен: когда приложение общается с API
- Как это работает вместе на примере Змейки
- Практический блок: как применить и проверить
- Частые ошибки новичков
- Заключение + чек-лист
Зачем отказываться от паролей в простом приложении
Пароль кажется простым: придумал, запомнил, ввёл. На деле он создаёт несколько проблем.
- Пользователи выбирают слабые пароли.
123456,qwerty, дни рождения — всё это легко подбирается. - Пароли повторяются. Если один сервис утёк, злоумышленники пробуют те же данные на других.
- Хранить пароли сложно. Даже захешированный пароль требует соли, медленных алгоритмов и постоянной бдительности. Ошибка в одной строчке — и база данных раскрыта.
- Пароль нужно восстанавливать. Забыл — жди письма, кликай ссылку, придумывай новый.
В небольшом проекте, где ты и сам разрабатываешь бэкенд, проще и безопаснее переложить проверку личности на почту или на внешний сервис вроде Google. Ты не хранишь секрет пользователя у себя — значит, не можешь его потерять.
Главная мысль: пароль — это секрет, который должен знать только пользователь. Если ты как разработчик не хранишь этот секрет, у тебя меньше ответственности и меньше рисков.
OTP: одноразовый пароль на почту
OTP расшифровывается как One-Time Password, то есть «одноразовый пароль». Это код, который действует короткое время и подходит только для одного входа.
В сценарии из курса работает так:
- Пользователь вводит свой email в форму входа.
- Приложение просит Supabase отправить письмо с кодом.
- На почту приходит шестизначный код. По умолчанию в Supabase он действует 1 час; срок можно изменить в Authentication → Sign In / Providers → Auth Providers → Email → Email OTP expiration.
- Пользователь вводит код в приложение.
- Supabase проверяет код: если он правильный и не просроченный, считает, что человек действительно владеет почтой.
Почта здесь выступает каналом проверки. Код — это не пароль, его нельзя использовать дважды и нет смысла запоминать. Если кто-то перехватит старый код, он уже не сработает.
Представь это как вход в подъезд по звонку в concierge: ты говоришь свой адрес, concierge звонит тебе на мобильный, ты называешь код из СМС — дверь открывается. Код работает один раз, и concierge не хранит у себя твои ключи.
Важно: OTP защищён ровно настолько, насколько защищена почта. Если у злоумышленника есть доступ к почтовому ящику, он сможет войти. Поэтому важные ящики лучше защищать двухфакторной аутентификацией самой почты.
Что такое сессия
После успешной проверки кода приложению нужно помнить, что ты уже вошёл. Иначе при каждом клике пришлось бы вводить email и код заново.
Сессия — это состояние «пользователь авторизован». В классической схеме сервер хранит запись и выдаёт браузеру идентификатор. Supabase использует другой вариант: сессия представлена короткоживущим JWT-токеном доступа и одноразовым refresh-токеном, а её идентификатор хранится в claim session_id и связан с записью в auth.sessions.
По умолчанию сессия Supabase не имеет фиксированного срока и остаётся активной, пока пользователь не выйдет или не сработает другое условие завершения. Ограничения максимального времени жизни, бездействия и числа одновременных сессий доступны на тарифе Pro и выше. Сам access-токен обычно живёт от 5 минут до 1 часа, после чего библиотека обновляет его через refresh-токен.
Сервер может отозвать сессию: например, если пользователь вышел. При этом уже выданный access-токен остаётся действительным до своего срока exp, если приложение отдельно не проверяет наличие session_id в auth.sessions.
Cookie: как браузер запоминает сессию
Браузер и сервер общаются по HTTP — протоколу, в котором каждый запрос по сути независимый. Без дополнительных механизмов сервер не отличит новый запрос от продолжения старого разговора.
Cookie — это маленький фрагмент данных, который сервер просит браузер сохранить и присылать с каждым следующим запросом. В классической серверной авторизации в cookie обычно хранится идентификатор сессии.
Когда ты вошёл по коду, сервер может сказать браузеру:
«Сохрани вот эту печеньку с номером сессии. Присылай её мне при каждом обращении, и я буду понимать, кто ты.»
Важные свойства cookie:
- HttpOnly — cookie недоступна JavaScript на странице. Это защищает от XSS-атак, когда злоумышленник пытается украсть данные через вредоносный скрипт.
- Secure — cookie передаётся только по HTTPS, то есть в зашифрованном виде.
- SameSite — ограничивает, когда cookie отправляется с запросами с других сайтов. Это защита от CSRF-атак.
- Expires / Max-Age — время жизни cookie.
Cookie не содержит пароль, но может быть ключом к активной сессии. Если злоумышленник завладеет такой cookie, он сможет действовать от имени пользователя до истечения или отзыва сессии.
В браузерном клиенте supabase-js сессия по умолчанию сохраняется не в HttpOnly-cookie, а в localStorage: JavaScript должен читать refresh-токен, чтобы обновлять сессию. Cookie применяются в серверных и SSR-сценариях с отдельной настройкой хранилища; HttpOnly-cookie подходит только приложению, где сессию читает и обновляет сервер.
Токен: когда приложение общается с API
Cookie хороши для классических веб-страниц, но современные приложения часто общаются с сервером через API. Здесь удобнее использовать токен.
Токен — это подписанная строка, которая подтверждает личность пользователя. Самый распространённый формат — JWT (JSON Web Token). Он состоит из трёх частей:
- Заголовок — информация о типе токена и алгоритме подписи.
- Полезная нагрузка — данные о пользователе, например ID и срок действия.
- Подпись — криптографическая проверка, что токен не подделали.
Токен выдаётся после входа. Приложение сохраняет его в памяти или в выбранном хранилище и прикрепляет к каждому запросу к API, обычно в заголовке Authorization: Bearer <токен>.
Сервер, получив токен, проверяет подпись и срок действия. Если всё в порядке — выполняет запрос. Если токен просрочен или подделан — отказывает.
Supabase использует access- и refresh-токены для доступа к базе данных и API. Когда ты входишь через OTP, Supabase возвращает сессию с токенами, и клиентская библиотека использует access-токен для запросов к таблицам — например, чтобы записать новый рекорд именно для этого пользователя.
Разница в двух словах: серверная сессия хранит состояние на сервере, cookie переносит идентификатор или токены между браузером и сервером, а JWT содержит подписанные данные, которые можно проверить без отдельного запроса к хранилищу сессий.
Как это работает вместе на примере Змейки
Представь, что в Змейке появилась таблица лидеров. Игрок хочет, чтобы его результат сохранялся под именем, а не терялся при закрытии вкладки.
- Игрок открывает игру и нажимает «Войти».
- Вводит email, нажимает «Отправить код».
- Supabase отправляет на этот адрес одноразовый код.
- Игрок вводит код, Supabase проверяет его.
- После успеха Supabase создаёт сессию и возвращает access- и refresh-токены.
- В обычном браузерном приложении
supabase-jsсохраняет сессию вlocalStorageи автоматически обновляет access-токен. - Когда игрок бьёт рекорд, библиотека отправляет результат в Supabase с access-токеном.
- Supabase видит по токену, кто именно установил рекорд, и записывает его в таблицу лидеров.
- При следующем открытии игры клиент восстановит сессию из хранилища — до тех пор, пока сессия не будет завершена.
Пароль при этом нигде не фигурирует. Ты не хранишь его в базе, не проверяешь сложность, не восстанавливаешь. Вся ответственность за подтверждение личности лежит на почтовом сервисе и на механизме OTP, который предоставляет Supabase.
Практический блок: как применить и проверить
Если ты собираешь авторизацию в своём проекте, пройди по этому чек-листу:
- Выбери провайдера аутентификации. Supabase — удобный вариант для проектов курса: в нём уже есть OTP, сессии, токены и клиентская библиотека для их обновления. Официальная документация: supabase.com/docs/guides/auth.
- Настрой отправку писем. Шаблоны находятся в разделе Authentication → Email Templates. Чтобы вместо magic link приходил код, добавь в шаблон переменную
{{ .Token }}. - Используй готовый клиент. Supabase предоставляет JavaScript-библиотеку, которая берёт на себя хранение токенов и обновление сессии.
- Выбери подходящее хранилище. Для браузерного SPA
supabase-jsпо умолчанию используетlocalStorage. Для SSR настрой cookie по официальному руководству и помни, что HttpOnly-cookie несовместима с обновлением сессии на клиенте. - Настрой срок действия access-токена. Для большинства приложений Supabase рекомендует значение по умолчанию — 1 час. Ограничения времени жизни самой сессии доступны на тарифе Pro и выше.
- Проверь выход.
supabase.auth.signOut()по умолчанию завершает все сессии пользователя; для выхода только на текущем устройстве передай{ scope: 'local' }. - Тестируй в режиме инкогнито. Открой игру, войди, закрой вкладку, открой снова — ты должен оставаться авторизованным. Затем нажми «Выйти» и убедись, что доступ к личным данным пропал.
Важно: никогда не пиши свой собственный криптографический механизм для сессий и токенов. Используй проверенные библиотеки и сервисы. Ошибки в самодельной аутентификации — один из самых частых источников уязвимостей.
Частые ошибки новичков
Ошибка 1. Хранить пароли или незащищённые токены в localStorage
Пароли нельзя сохранять в localStorage ни при каких условиях. supabase-js хранит там сессию по умолчанию, поэтому защита браузерного приложения от XSS критична: любой внедрённый JavaScript сможет прочитать токены. Если приложение рендерится только на сервере, можно выбрать серверное хранилище с HttpOnly-cookie; для клиентского SPA такая cookie не даст библиотеке обновлять сессию.
Ошибка 2. Не проверять срок действия токена
Токены не вечны. Если приложение не обновляет токен и не обрабатывает ошибку «истёк», пользователь внезапно увидит страницу, на которой ничего не работает.
Ошибка 3. Доверять данным на клиенте
Нельзя решать на стороне браузера, что пользователь может видеть чужой рекорд. Правила доступа должны проверяться на сервере — например, через Row Level Security в Supabase.
Ошибка 4. Забывать про кнопку «Выйти»
Выход должен работать полностью: и на фронтенде, и на бэкенде. Иначе сессия останется активной, и кто-то другой сможет ей воспользоваться. Учитывай, что отозванный access-токен Supabase может оставаться действительным до времени exp.
Заключение + чек-лист
Авторизация без пароля через OTP — простой и безопасный способ узнавать пользователей в небольших приложениях. Вместо того чтобы придумывать и хранить секреты, ты передаёшь проверку личности почте и внешнему сервису. Сессия запоминает, что человек вошёл, выбранное хранилище сохраняет её между открытиями приложения, а токен позволяет обращаться к API.
Для проекта вроде Змейки, где нужны аккаунты и таблица лидеров, этот подход удобен: он работает «из коробки» в Supabase, не требует ручного управления паролями и понятен новичкам.
Чек-лист «Авторизация настроена правильно»
- Вход реализован через OTP или внешнего провайдера, пароли не хранятся в проекте.
- Сессия завершается при выходе, а дополнительные ограничения её времени жизни настроены при необходимости.
- Для SSR cookie настроены с подходящими флагами Secure и SameSite; HttpOnly используется только при серверном обновлении сессии.
- Токены обновляются автоматически и проверяются на сервере.
- Правила доступа к данным настроены на бэкенде, а не только на клиенте.
- Проверено: после закрытия вкладки пользователь остаётся авторизованным.
- Проверено: после нажатия «Выйти» доступ к личным данным пропадает.
- В письмо с кодом добавлены понятный текст и срок действия кода.
Итог: не усложняй то, что уже придумано до тебя. Используй OTP, сессии и токены через проверенный сервис, и у тебя получится безопасный вход без головной боли с паролями.
Читай дальше
Все статьиНе просто статьи — тебя доведут до результата
В практикуме за 2499 ₽ рядом живая команда практикующих разработчиков и маркетологов: ведём по шагам до твоего работающего приложения. Не «ролики и сам разбирайся» — помогаем на каждом затыке.
Перейти к практикуму