Как Ускорить Аутентификацию И Уменьшить Потребление Памяти В 5 Раз? Нанять Дворецкого

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

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

Меня зовут Роман Литвинов, я разработчик команды Учи.

ру.

Я хочу рассказать вам именно эту историю из практики и о нашем сервисе под названием Батлер, о «дворецком», через который проходит каждый пользователь перед входом на платформу.

Итак, овсянка, сэр.



Как ускорить аутентификацию и уменьшить потребление памяти в 5 раз? Нанять дворецкого

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

Когда весной 2020 года база данных Учи.

ру выросла до более чем 11 миллионов активных пользователей (8 миллионов учеников, примерно 350 тысяч учителей и около 3,5 миллионов родителей), существующая реализация стала медленной, непрозрачной и потребляла слишком много памяти.

Мы решили обновить его.

Мы ставим перед собой следующие цели:

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

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

В список новых возможностей входят:

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



Сложность работы с таблицами.

Роли пользователей



Длительная аутентификация

Учи.

ру посещают разные пользователи: студенты, их родители, преподаватели (в том числе учителя или завучи), а также администраторы.

Изначально для каждой из этих категорий пользователей была создана отдельная таблица.

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

Но когда пользователей стало почти в полтора раза больше, это стало занимать значительное время, до 2?–3 секунд.

Проблема уникальности почты и логина

Если родитель также является учителем и хочет зарегистрироваться на Учи.

ру, ему необходимо создать две учетные записи.

Это означает, что его адрес электронной почты будет указан в двух разных таблицах.

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

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

То есть различаются только пароли у детей в одной школе.



Теперь мы используем Батлера

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

Для этого и был создан Батлер.

Саму аутентификацию было решено провести на основе открытой библиотеки Ruby под названием родаут .

Конечно, его пришлось немного доработать, но в целом решение подошло.

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

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

В нашем случае это не могли быть логины, почта и телефон.

Поэтому нам пришлось создать для студентов дополнительное поле stud_hush — комбинацию логина и пароля в виде хеш-суммы.

Все пользователи были переведены из нескольких таблиц в единую базу данных.

Принадлежность к разным таблицам раньше позволяла нам определять роли и записывать их в отдельный столбец.



Как ускорить аутентификацию и уменьшить потребление памяти в 5 раз? Нанять дворецкого

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

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

Но нужно было заставить такое решение работать с оставшейся частью монолита.

Для этого нам пришлось сформировать дополнительный запрос от имени пользователя.

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

Небольшое тюнинговое решение

Конечно, нам пришлось изменить настройки среды.

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

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

И, как правило, с одного и того же смартфона в систему заходит один и тот же человек.

А дети младшего возраста иногда испытывают трудности с входом.

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

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



Обновление — камень преткновения

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

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

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

Раньше это было необязательно и ускользало от нашего внимания.

Это означает, что все выпущенные токены сразу перестанут работать, если мы выпустим это обновление.

То есть, если бы мы обновили всю систему сразу, она сбросила бы все активные сессии.

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

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

За это время в системе работали как связанные, так и несвязанные токены.

Платформа не предоставляла такой функции; Мне пришлось добавить это самому.



Криптография и защита от грубой силы

При хранении логинов и паролей в новой базе данных в зашифрованном виде дополнительной «тормозной точкой» стал один из самых используемых алгоритмов в экосистеме — Ruby BCrypt. Его реализация на Ruby была слишком ресурсоемкой для ЦП: создание хэша занимало 250 мс со стандартной стоимостью 12. Эту операцию часто приходится выполнять дважды в течение цикла вопрос-ответ, поскольку она требует проверки, использовал ли пользователь тот же пароль ранее.

.

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

На этих самых коллбеках висело слишком много бизнес-логики, что не позволяло свести проблему к простому рефакторингу.

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

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

Для этого потребовалось внести изменения в саму библиотеку Rodauth. К счастью, ее автор Джереми Эванс оказался очень открытым человеком и пошел нам навстречу.

В сервисе Rodauth также есть встроенное решение для защиты от подбора паролей.

После определенного количества попыток аккаунт блокируется на некоторое время.

Разблокировка может быть осуществлена путем подтверждения по электронной почте или вручную.



Перенос аккаунтов

Данные о пользователях были распределены по нескольким таблицам для каждой роли.

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

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

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

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

Чтобы исторические данные могли использоваться аналитиками, необходимо было вручную корректировать все «грязные» записи.

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

В некоторых аккаунтах нам приходилось разносить имя и фамилию по разным полям, в других исправлять роли или корректировать данные о принадлежности к школе.

В результате нам удалось сохранить историю регистрации наших пользователей для дальнейшего изучения и бизнес-аналитики.



Результаты

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

Разработчикам теперь немного сложнее: они не могут просто скачать копию монолита и проверить свои гипотезы.

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

Но я уверен, что мы все легко к этому привыкнем.

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

При этом он также работает на базе Ruby, как и основная часть системы Учи.

ру.

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

Теги: #информационная безопасность #Микросервисы #Распределенные системы #аутентификация #аутентификация пользователя #argon2 #it-миграция

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.