Инструкция: как написать идеальную регистрацию

Создаём удобную, безопасную и архитектурно грамотную регистрацию через email и соцсети. Ну и логин с восстановлением доступа, конечно.

Инструкция: как написать идеальную регистрацию

Небольшое вступление

Регистрация является неотъемлемой частью большинства цифровых продуктов. Мы постоянно заводим новые аккаунты, придумываем сложные (или нет) пароли, у многих даже есть специальная почта для этих нужд.

Однако давайте вспомним, как часто мы встречали идеальную регистрацию? Почему даже крутые компании не могут сделать удобную и безопасную систему логина и восстановления доступа? Кажется, что все продуктовые дизайнеры настолько свыклись с тем, что регистрация — это просто, что даже не прилагают особенных усилий для её проектирования.

Простой пример. Кто из нас не сталкивался с тем, что тупит перед формой входа, не помня, как именно он регался на этом сервисе: через почту или какую-то из соцсетей? И таких примеров тьма. Но самое грустное в том, что мы сами считаем это нормой, и чаще всего виним себя и свою забывчивость, тогда как чаще всего виноват в этом именно сервис.

Я решил написать подробную инструкцию без привязки к конкретному языку программирования или методологии проектирования. Чистая логика, которую каждый без труда сможет подогнать под себя и реалии своего проекта.

Опыт в разработке и продуктовом дизайне тут тоже не особенно важен: начинающие могут использовать эту статью в качестве пошагового руководства; опытные же, возможно, почерпнут из неё какие-то отдельные удачные решения.

Оглавление

1. Концепция

1.1. Задача

Реализовать схему регистрации, аутентификации и восстановления доступа посредством email и соцсетей.

Из-за универсальности инструкции, не допускается привязка к конкретным фреймоворкам, базам данных или программным решениям.

Кроме того, в схеме не реализована двойная аутентификация, так как она предполагает определённые технические решения (например, TOTP или SMS), которые также могут быть продиктованы особенностями продукта или бизнес-логики.

1.2. Формат

Инструкция представлена в виде набора сценарных схем с пояснениями. Отдельно описываются сложные или не очевидные сценарные моменты.

Каждый экран, используемый в схемах, имеет своё название и состояние. Состояние может определять внешний вид или логические особенности (например, состояние «ValidationError» подразумевает сообщения об ошибках валидации формы).

Легенда для схем, используемых в инструкции (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-legend.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Легенда для схем, используемых в инструкции (SVG)

Каждый серый (клиент) и синий (сервер) блок является функцией разрабатываемой системы. Такие функции не описываются отдельно, так как их реализация может зависеть от особенностей конкретного языка или программного окружения.

Важное значение имеют соединительные линии (стрелки) на схемах. Они могут быть двух видов: сплошные (переходы) и пунктирные (обмен данными). На основании пунктирных линий можно, например, спроектировать API.

2. Регистрация через email

Регистрация пользователя через email осуществляется в два этапа:

  1. заполнение формы регистрации;
  2. подтверждение email.

Поля, заполняемые пользователем при регистрации, могут быть произвольными. Однако в их числе обязательно должны быть поля «email» и «пароль»: первое используется как универсальный идентификатор, второе косвенно определяет тип регистрации (при регистрации через соцсети пароль не создаётся).

2.1. Заполнение формы

Наличие аккаунта

При регистрации через email, проводится проверка на наличие почты в базе данных. Если пользователь с таким email уже зарегистрирован, то происходит передача управления процессом общей функции «проверка на привязанные соцсети».

Временный аккаунт

До того, как пользователь не подтвердил свой email, его аккаунт является временным. Это позволяет:

  • более гибко управлять правами доступа (например, таким пользователям можно ограничить набор разрешённых действий);
  • автоматически очищать базу от неактивированных аккаунтов (например, по прошествии определённого времени).

В базе данных временный аккаунт может отличаться от обычного простым булевым флагом — или же такие аккаунты могут вообще храниться в отдельной таблице.

Схема регистрации через email (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-registration.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема регистрации через email (SVG)

2.2. Подтверждение

Подтверждение email классическое: ссылка с GET-параметрами в письме.

Срок жизни подтверждающей ссылки

В случае, если в вашем сервисе работает «очистка» БД от неактивных аккаунтов, разумно установить срок жизни подтверждающей ссылки, который будет несколько меньше, чем период присутствия временных аккаунтов в базе. Это исключит ошибки, когда пользователь пытается подтвердить почту, а его временный аккаунт уже удалён.

Повторное подтверждение

В ряде случаев имеет смысл обрабатывать повторный переход по подтверждающей ссылке, и показывать пользователю сообщение «email уже подтверждён». Этого нет в схеме, так как автор однажды столкнулся со злоупотреблением подобной функциональностью. Однако если вы уверены, что для вашего продукта это не проблема — рекомендую реализовать.

Схема подтверждения email после регистрации (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-registration-confirm.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема подтверждения email после регистрации (SVG)

3. Регистрация и логин через соцсети

При использовании соцсетей схема регистрации во многом использует те же механизмы, что и логин — поэтому здесь они объединены.

Соцсеть не вернула email

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

Если пользователь с таким email уже зарегистрирован, то происходит передача управления процессом общей функции «проверка на привязанные соцсети».

Если пользователя с таким email нет в базе данных, запускается стандартная процедура отправки подтверждающего письма (описана в разделе «регистрация -> подтверждение»).

Объединение аккаунтов

Если пользователь с email, который вернула соцсеть, уже зарегистрирован в системе, то проводится проверка на соответствие прикреплённой к его аккаунту соцсети.

Если соцсеть та же, которую использует пользователь в настоящий момент, то пользователь успешно аутентифицируется (общие функции «запись успешного входа» на сервере и «успешная аутентификация» на клиенте).

Если соцсеть отличается от той, которую использует в настоящий момент пользователь, или пользователь был зарегистрирован с помощью email, то к существующему аккаунту добавляется текущая соцсеть, и уже тогда происходит успешная аутентификация (аналогично случаю выше).

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

Схема регистрации через соцсети (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-social.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема регистрации через соцсети (SVG)

4. Логин (аутентификация)

Механика логина максимально простая: пользователь вводит email и пароль, после чего сервер проверяет их на соответствие.

Шифрование

Крайне рекомендуется хранить пароли в БД в хэшированном виде (не MD5), использовать дополнительные «соли» для лучшей безопасности (спасибо Saucedo Puetz за поправку в комментариях).

Защита от брутфорса

Способ защиты от перебора часто связан с конкретным программным решением или библиотекой, которую вы используете. Могут учитываться сессии, куки, ip-адреса, вспомогательные факторы (вроде включенного JS) и многое другое. Не забывайте про защиту от перебора, это важно.

Схема аутентификации (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-login.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема аутентификации (SVG)

5. Восстановление доступа

Восстановление доступа к аккаунту осуществляется в два этапа:

  1. заполнение формы восстановления;
  2. подтверждение: переход из письма и ввод нового пароля.

5.1. Заполнение формы

Подстановка email

Если пользователь в рамках текущей сессии уже вводил email в формах регистрации или логина, то при переходе к восстановлению доступа, соответствующее поле предзаполняется.

Отсутствие пароля

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

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

Схема восстановления доступа (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-restore.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема восстановления доступа (SVG)

5.2. Подтверждение

Срок жизни подтверждающей ссылки

Крайне желательно, чтобы ссылка на смену пароля не была «вечной». Это позволит избежать множество неприятных ситуаций. Поэтому при проверке ссылки на сервере мы, в числе прочего, проверяем и её срок действия.

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

Деактивация подтверждающей ссылки

Ну и разумеется, мы не можем позволять пользователям несколько раз сбрасывать пароль по одной и той же ссылке (банальный перехват URL позволит вытворять непозволительные вещи). Поэтому после первого перехода из письма ссылка будет деактивироваться.

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

Автологин

После перехода по ссылке из письма мы не будем заставлять наших пользователей заново входить в аккаунт. Сам факт доступа к почте с возможностью последующей смены пароля упраздняет необходимость введения дополнительных мер безопасности в виде логина. Поэтому аутентификация происходит автоматически, как только был проверен ключ из ссылки.

Дополнительно, вы можете реализовать механизм принудительной смены пароля (чтобы после логина не перенаправлять пользователя в аккаунт, например). Но это уже на ваш вкус и реалии продукта.

Схема подтверждения сброса пароля через email (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-restore-confirm.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Схема подтверждения сброса пароля через email (SVG)

6. Общие функции

Для упрощения архитектуры в этот раздел вынесены функции, которые используются более одного раза в системе. Их можно реализовать отдельно и обращаться к ним по мере необходимости. Удобно, быстро и сильно стабилизирует как саму разработку, так и поддержку продукта.

6.1. Клиент

Показ сообщений

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

Валидация

Тоже не сложно. Как правило, типов полей форм, которые надо валидировать, максимум 3-4, плюс один кастомный, по маске (RegExp). Логично вынести валидацию в отдельную функцию и применять к конкретным полям по необходимости. Благо, для любого фреймворка есть куча готовых решений на эту тему.

Отправка данных

Стандартный механизм асинхронной отправки с обработкой результата. Как правило, имеется в любом фреймворке «из коробки», но иногда имеет смысл расширить функциональность (например, за счёт URL’ов API, помещённых в константы).

Успешная аутентификация

Функция успешного логина. Подразумевает последующее перенаправление на целевую страницу. В схеме целевая страница представлена профилем с дефолтным состоянием (Nav.Profile, Default), однако хорошим тоном считается запоминать URL, с которого был вызван логин, и возвращать на него пользователя после успешной аутентификации.

Подсказка по логину через соцсети

Иллюстрация решения проблемы из начала статьи (когда пользователь не может вспомнить, через какую соцсеть он входил).

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

Эта функция может быть вызвана везде, где есть необходимость регистрации или логина (на отдельных страницах, в форме комментариев и тп), однако её программная реализация может зависеть от механик авторизации конкретной соцсети или сервиса.

6.2. Сервер

Очистка данных

Любые данные, попадающие на сервер из клиента (и не только), должны быть в обязательном порядке очищены от всякой гадости, вроде SQL-инъекций или неприятных штук вроде XSS. Это действительно важно, потому что потом может сказаться на жизнеспособности всего продукта и безопасности данных его пользователей.

Валидация

Аналогично функции на клиенте, можно написать отдельную функцию валидации данных на сервере, которая будет принимать в качестве параметров сами данные и тип валидации (включая регулярные выражения). Вызывать такую функцию можно буквально в пару строк.

Отправка email

Для многих языков и фреймворков есть готовые нативные решения по отправке email (в том числе, с помощью SMTP). Так как письма могут отправляться из многих частей продукта, логично использовать для этого единую функцию.

Запись успешного входа

Очень часто нужно отслеживать активные сессии пользователя или сообщать ему о новых логинах. Для этого как минимум потребуется фиксировать все случаи успешной аутентификации. Можно записывать их в БД или вести отдельный лог — как вам удобнее.

Проверка на привязанные соцсети

Функция вызывается в результате проверки наличия email в базе данных. Если пользователь с таким email уже зарегистрирован, то происходит проверка на наличие привязанных соцсетей. В зависимости от результата проверки пользователю предлагается войти через соцсеть (если найдена привязанная) или с помощью почты и пароля.

7. Итоговая схема

Абсолютно нечитаемая (особенно в рамках сайта), но исчерпывающая схема всего того, то было описано в этой статье. Может пригодиться архитекторам, которые хотели бы выявить дополнительные общие функции или оценить объём предстоящих работ.

Общая схема регистрации, логина и восстановления доступа (<a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsherer.pro%2Fcontent%2Fuploads%2F2020%2F09%2Fauth-scheme-all.svg&postId=156552" rel="nofollow noreferrer noopener" target="_blank">SVG</a>)
Общая схема регистрации, логина и восстановления доступа (SVG)

В завершение

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

Я много пишу про проектирование, разработку и продюсирование IT-проектов, и все свои материалы агрегирую в уютном телеграм-канале, велкам.

6666
42 комментария
150 ₽

Отлично, спасибо большое за инструкцию! То, что надо!

7

Боги сошли с небес и детально написали ТЗ

12

Развели тут хабр 

10

При том не просто хабр, а хабр-торт!

6

С точки зрения безопасности использовать для идентификации email. идентификация должна быть по логину а email всегда скрыт.
И да, пароли не шифруются а хэшируются!

1

Насчёт email спорно. Во-первых, логин — это неудобно, все привыкли вводить почты. Во-вторых, email нигде, кроме восстановления, можно и не светить. Да и там, при необходимости, можно повесить защиту от перебора.

Касаемо хэширования да, согласен, запарился. Исправил в статье.

10

Инструкция огонь. Делали подобные вещи для проекта реши-пиши с нуля и до всего из статьи доходили со временем ;-) Прочитать бы раньше... Но ещё будем прикручивать соцсети, так что обязательно перечитаю и сделаю подсказки через какую соц сеть логинились, если сессия пропала и в куках помним. Так просто и удобно!

3