Вашим пользователям не нужны пароли

Rusty lock


Зачастую, одно из первых архитектурных решений, принятых в начале разработки вашего сайта — будет использование email + password для авторизации пользователя. Эта связка прочно засела в наши головы, и мы уже на задумываемся, зачем мы заставляем людей придумывать пароль. Мы привыкли так делать.


Но давайте подумаем, возможно, вашим пользователям не нужны пароли.


Одно из возможных решений, это использовать OAuth 2.0, но не у всех пользователей может быть аккаунт в социальной сети и желание его использовать на вашем ресурсе.


Но как-же тогда избавиться от пароля? На этот вопрос, я и попробую ответить в статье.


А в чем проблема?


Единственный защищенный пароль — это тот, который вы не в силах запомнить.

Troy Hunt

Сам по себе пароль уже является проблемой. Он не выгоден, ни вам, ни вашим пользователям.


Для владельца сайта пароль не выгоден тем, что его хранение создает дополнительную уязвимость в системе. Каким бы сильным ни был ваш хеширующий алгоритм (и упаси вас господь, не использовать его) рано или поздно он станет пустяком для новых GPU, а в последствии и CPU. А если ваша база данных утечет в сеть, то это нанесет колоссальный удар по вам и вашим посетителям. Без паролей же база становится в разы менее лакомой добычей.


Для посетителей вашего сайта, пароль — это дополнительные трудности. Неопытные пользователи будут лишний раз использовать свой «обычный» пароль, повышая риск потерять его. А продвинутые пользователи будут вынуждены придумывать специальный пароль для вашего сайта или пользоваться менаджером паролей.


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


Помимо этого, вы можете дополнительно отравить жизнь вашим пользователям, заставив их периодически менять их, или запретить / заставить использовать специальные символы.


Как же быть?


Ответ — не использовать пароли. Вам достаточно знать только email пользователя.


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


Сброс пароля уже звучит как оксюмороном. Ведь для того, чтобы задать новый пароль достаточно лишь получить письмо на email. Все. Так и зачем же вы заставляли пользователя придумывать пароль, менять его и использовать только угодные вам символы?


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


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


Решение


Рассмотрим пример простого сайта с PostgreSQL в качестве базы данных.


Нам будет достаточно двух таблиц (с минимальным набором полей):


users:


Имя поля Тип данных Атрибуты
id serial PRIMARY KEY
email varchar(320) UNIQUE


sign_in_requests:


Имя поля Тип данных Атрибуты
id serial PRIMARY KEY
email varchar(320)
token uuid UNIQUE
is_used boolean
request_ip varchar(45)
expired_at timestamp


Несколько комментариев на счет таблиц:


  • Таблица sign_in_requests может (и должна) быть общей с «Sign Up» таблицей, т.к. в этой системе их роль идентична.
  • Исходя из пункта выше, в sign_in_requests отсутствуют внешние ключи, а поле email дублируется.
  • token не обязан быть uuid’ом, вы можете сделать и более короткие токены, которые можно даже ввести вручную. Но в этом случае вероятность коллизии и его надежность могут значительно ухудшиться.
  • request_ip — опциональное поле, используется только для rate limit’а, или дальнейшего выяснения причин.


Процесс авторизации весьма прост:


  1. Пользователь вводит свой email и делает запрос.
  2. Вы генерируете sign_in_request, и высылаете на почту пользователя ссылку вида: https://example.com/signin/callback/email/{{token}}.
  3. Пользователь, перейдя по этой ссылке делает запрос к вашей базе на наличие такого token’а.
  4. Если такой токен есть, он не просрочен, и он последней с таким email (опциональная защита от Brute Force), то считаем, что все хорошо.
  5. Выставляем is_used=true, чтобы предотвратить множественное использование токена.
  6. Далее, все так-же, как и в системе с паролями, вы можете дать пользователю cookie / JWT / etc.


В качестве защиты от спама письмами, можно сделать рейт лимит, или не высылать письмо чаще чем раз в 10 минут.


Для кого?


Кому стоит использовать данную технику:


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


И не стоит использовать данную технику:


  • Когда вы сами являетесь email сервисом.
  • Ваш основной клиент — это мобильное приложение / Smart TV / IoT. В этом случае, возможно, стоит оставить опциональную возможность использования пароля.


Финальные слова


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


Источник изображения: https://pixabay.com/en/padlock-grunge-rusty-rusting-76866/

© Habrahabr.ru