Реализуем идеальную аутентификацию в вашем JS-приложении
По материалам доклада на JS Fest Autumn 2019, Киев
В данной статье мы рассмотрим процесс внедрения аутентификации с двух точек зрения:
- со стороны разработчика, и как эффективно её реализовать;
- со стороны бизнеса — как добавить аутентификацию в свое приложение, не потратив при этом все деньги мира.
Для начала давайте определимся с разницей между аутентификацией и авторизацией.
Аутентификация — процесс установления личности пользователя.
Авторизация — процесс установления прав этого пользователя относительно какого-то ресурса.
При правильном подходе к реализации аутентификации нужно учесть все возможные «скользкие места». Это могут быть:
- потенциальные уязвимости (security);
- риски;
- стоимость реализации.
Конечно, можно минимизировать ошибки, отдав этот вопрос профессионалам, вместо того, чтобы заниматься самому. Если же вы подумываете над самостоятельной реализацией, то вот что необходимо продумать в первую очередь:
- Registration flow — регистрация пользователя (за исключением B2B систем, где часто пользователю предоставляют данные для аутентификации).
- Password reset flow — путь сброса и восстановления пароля.
- Credentials validation — валидация имени, пароля пользователя, а также других данных, которые у вас есть.
- Error handling — правильная обработка ошибок.
- Error messages — вывод сообщений об ошибках.
- Localization — настройка локализации этих сообщений.
- Brute-force attacks protection — возможность оперативно реагировать на попытки взлома, DDOS-атаки, а также предотвращать их.
- Email template — создание красивого шаблона письма с регистрационными данными юзера.
Дополнительно желательно настроить:
- Функцию «Remember me».
- Возможность блокировки пользователей.
- Журнал событий — чтобы знать, кто заходил в приложение и что он там делал.
- Выявление аномалий. Например: пользователь только что зашел из Киева, а через 5 минут — из Лондона, как он так быстро переместился?
- Мультифакторную аутентификацию.
- Глобальный выход из системы — чтобы прекратить сессии на всех устройствах пользователя.
Если говорить о мире JavaScript, то есть безоговорочный лидер среди библиотек для аутентификации. Это — Passport.js. Данная библиотека, по заявлению разработчиков, поддерживает около 500 разных стратегий (способов) аутентификации. Использование Passport.js существенно упрощает разработку, но все же, при использовании внешних сервисов для аутентификации, требует разбираться с особенностями каждого сервиса.
Но существует более оптимальный подход. Можно взять готовое решение. Не продумывать все моменты, описанные выше, а взять готовую платформу, которая будет включает в себя identity management, администрирование, управление пользователями, а затем интегрировать её в свое приложение.
Плюсы:
➕ Гибкость, ведь такие системы делаются для всех, имеют много фич, их можно кастомизировать. Особенно, если это open source, который можно расширить под ваши нужды и не брать готовый docker-образ для постоянного использования.
➕ Подобная реализация относительно недорогая. Важно помнить, что когда создаете что-то свое, вас ждет длинный тернистый путь с множеством бережно разложенных граблей. При использовании готового продукта все эти грабли там тоже лежат, но на них уже наступали, поэтому вероятность проблем минимальна.
Минусы:
➖Если в готовом решении что-то не работает или не подходит именно вам, вы остаетесь с проблемой один-на-один.
➖Очень крутая кривая обучения. Ведь у готового продукта, как правило, много документации, с которой нужно будет ознакомиться. Для этого нужно время. Кроме того, обычно ценники на те решения, которые вы можете разместить у себя и которые являются проприетарными, на порядок выше, чем аналогичные облачные сервисы. Вы платите за лицензию, и вам также нужно подумать про highly available инфраструктуру. Необходимо найти DevOps специалиста или администратора, а также команду людей, которая будет это поддерживать. Это потянет значительные расходы.
➖Зависимость от конкретного вендора. Кто-то готов использовать стандартный протокол (например, OpenID Connect). К сожалению, до того момента, как ваше приложение будет интегрироваться с этим стандартным протоколом, вам придется сделать много специфичных задач для этой платформы, и таким образом получить зависимость от вендора.
На рынке имеется несколько популярных решений — как проприетарных, так и опенсорсных.
Из опенсорсных это:
- Shibboleth
- Keycloak
- WSO (хоть и написано на Java, но для JS можно взять его Identity Management, который является standalone модулем)
Из проприетарных довольно популярен FusionAuth.
При выборе selfhosted решения, мы обычно стараемся найти что-то опенсорсное. Ведь чаще всего не хочется платить за лицензию, а также удобнее использовать продукт на предсказуемых условиях. Важно помнить, что бесплатный ≠ свободный продукт и наоборот. Ведь лицензию могут поменять в любой момент, или же бывает двойное лицензирование, когда комьюнити фичи лежат в публичном доступе, а необходимые функции является частью enterprise/premium предложения с высоким ценником.
Аутентификация как сервис
Это подход, решения которого круто выглядят, легко интегрируются, при котором можно быстро развивать свой продукт (т.е. можно быстро подключить и делать все необходимое), но который является достаточно сложным и при неправильном использовании дорого стоит.
У таких решений имеется много достоинств:
- Почти нулевой time to market: купить подписку на сервис, добавить минимальное количество кода в свое приложение, и все — у вас уже есть аутентификация. Не нужно думать о том, как это поддерживать, как масштабировать.
- Плата за каждого юзера. Очень удобно, например, если вы стартап на ранней стадии и пользователей у вас 0, то и платить ничего не нужно.
- Не нужно тратить время и деньги на реализацию.
- Не нужно это все поддерживать и сопровождать.
- Тесная интеграция с облачными платформами. Если вы используете Firebase Auth или AWS Cognito — это хорошо интегрируется с вашей облачной платформой. В основном это значит, что вы сможете сэкономить. Потому что если ваша аутентификация и авторизация интегрируется с вашим облаком, возможно, вам не нужно будет думать о доступах к своим ресурсам. Например, в AWS Cognito вы можете ограничить доступ к базам данных либо к части базы данных просто на основании того факта, что ваш юзер хранится в Cognito, т.е. вы избавляетесь от большого количества кода. Кроме того, вся эта логика выполняется на инфраструктуре вашего облачного провайдера, вы для этого не пишете код, не хостите его, а значит — вы за это не платите(по крайней мере, напрямую).
- Гибкие в плане GDPR и многих других стандартов, которые связаны с личными данными. Аутентификация часто происходит с использованием личных данных, а также эти данные могут хранится как часть информации о пользователе. Вскоре вы зададитесь вопросом, как сделать продукт совместимым с GDPR? Одно из требований GDPR и подобных регуляций — это хранить данные в зашифрованном виде (иногда и в определенном).
- Если вы писали решение сами или делали self hosted решение, вам нужно будет поднять вашу инфраструктуру физически в каком-то дата-центре и поддерживать ее там.
- В случае с облачными провайдерами — зайти в админку и нажать галочку, чтобы данные пользователей хранились в Европе.
Недостатки подхода:
- Плата за каждого пользователя. Если на этапе стартапа это преимущество, так как у вас еще нет пользователей, то когда вы подрастёте, это потянет нехилый бюджет.
- Вы не поддерживаете сервис, он масштабируется автоматически. Сервис практически никогда не «падает», но если вдруг «упадет», то «лежит» серьезно, пока его не поднимут вендоры, хоть обычно это происходит достаточно быстро.
- Проблемы с настройкой под себя. Если вам нужно будет использовать ваше лого, фирменные цвета и т.д., заранее подумайте, можно ли такое реализовать в готовом решении и
- можно ли вендора «убедить» предоставить вам такую возможность.
Краткий обзор сервисов облачной аутентификации
Из популярных сервисов для облачной аутентификации можно выделить:
- Okta
- Auth0
- AWS Cognito
- Firebase Authentication
Из всех вышеперечисленных сервисов, Okta, является наименее «хипстерским», самым дорогим, и у них, наверное, наибольшее количество фич, таких как управление пользователями для облачных приложений, возможность менеджмента пользователей через active directory.
Обзор сервиса Auth0
Преимущества Auth0
- Разработан компанией, специализирующейся на authentication и authorization сервисах.
- Хорошо интегрируется с разными платформами и языками.
- Предоставляет Hosted UI.
- Client-side и server-side SDK.
- Поддержка MFA.
- Passwordless/One-time-password (OTP) sign-in.
- Self-hosted для enterprise решений.
Слабые стороны AWS Cognito
- Standalone продукт, требует дополнительной интеграции в вашу инфраструктуру.
- Не быстрый саппорт для базовых подписок.
- Мощный сервис, но несколько сложный.
- Поддержка HIPAA и других стандартов только для enterprise лицензий.
Auth0 предоставляет только аутентификацию и авторизацию (как и в Okta, все остальное идет в связке с каким-то облачным провайдером). Имеет глубочайшую экспертизу и широкий спектр инструментов. Легко интегрируется со множеством платформ, с разными языками, у него много SDK и библиотек. Если у вас какой-то достаточно экзотичный язык, то Auth0, скорее всего, его поддерживает. Если вы используете нестандартные клиентские фреймворки — вполне вероятно, что для Auth0 либо уже есть решение, либо кто-то над этим работает. Очень легко кастомизируется. Есть готовая Hosted UI. В сервис можно добавить MFA, так как это очень хорошо для безопасности. Есть и такая интересная штука, как Passwordless/OTP sign-in (одноразовый пароль). Сервис можно использовать как облачное решение, а можно захостить у себя в инфраструктуре, однако стоит это недешево.
Из недостатков Auth0 хочется упомянуть то, что вся интеграция с вашей инфраструктурой лежит на вас. Если нужно что-то проверить или поменять — нужно лезть в Auth0 через API. Для небольших компаний это не страшно. На больших масштабах сложнее, так как тут играет роль специфика работы с современными облачными провайдерами. Входящие данные — бесплатно. Запросы к сторонним ресурсам — платно. Поскольку при авторизации и аутентификации подобные запросы мы будем делать часто, это влетит в копейку.
Также стоит помнить, что в дешевых тарифных планах support отностительно труднодоступен. И HIPAA compliance есть только в дорогом тарифе Enterprise.
Обзор AWS Cognito
Преимущества AWS Cognito
- Предоставляется как часть платформы Amazon Web Services(AWS).
- Поддерживает OIDC и SAML Federation.
- Поддерживает web, iOS и Android клиенты.
- Предоставляет client-side и server-side SDK.
- Хорошо интегрирован с AWS сервисами и может выдавать токены для доступа.
- Поддерживает Hosted UI.
- Поддерживает MFA.
- Совместим с HIPAA, PCI DSS стандартами «из коробки».
Слабые стороны AWS Cognito
- Hosted UI слабо кастомизируется по сравнение с конкурентами.
- API работает очень медленно.
- Низкие API rate limits(можно увеличить через техподдержку).
- Search API неудобный, разве что вам достаточно базового поиска по имени и e-mail.
- Очень мало готовых интеграций с внешними системами.
Обзор Firebase Authentication
Преимущества Firebase
- Хорошо интегрирован с Google Firebase.
- Предоставляет SDK для многих платформ, включая C++ и Unity.
- Гибкая конфигурация email адресов и email actions.
Слабые стороны Firebase
- Не поддерживает HIPAA стандарт (но есть альтернативные решения).
- Не поддерживает SAML «из коробки».
При выборе облачного сервиса рекомендуется подумать над следующим:
- Какие платформы поддерживаются, чтобы потом дополнительно не писать клиентские библиотеки под сервис.
- Если это существующее приложение, необходимо подумать о том, как импортировать туда текущих юзеров, чтобы воссоздать его уже в облаке. Обычно облачные сервисы используют для этого batch импорт. Это не очень хорошее решение, ведь в таком случае вы даете сервису CSV-файл, он его обрабатывает, и в итоге ваши пользователи получают e-mail, в котором их просят сбросить пароли. Такие сообщения могут выглядеть настораживающе для пользователей, поэтому нужно хорошо обдумать процесс перехода.
- Как можно сделать резервную копию данных пользователей с облачного сервиса. Такие сервисы не отдают данные по паролям, так как в таком случае это уже нарушило бы все требования безопасности. В случае резервной копии, скорее всего тоже придется попросить пользователей сбросить пароль.
- Потенциальные финансовые риски, которые станут очевидными в тот момент, когда вы начнете развиваться и расти. Например, плата за пользователя при переходе с базовой версии сервиса на более продвинутую. Иногда отличается в десятки раз.
- Как часто «падает» сервис и насколько доступна вам поддержка. В бюджетных версиях сервисов очень часто с ней можно связаться только по email и получить ответ только через несколько дней.
Сколько стоят облачные сервисы
Количество пользователей | Auth0 | AWS Cognito | Okta | Firebase |
1K | $23/mo | $0/mo | $0/mo | Free |
10K | $228/mo | $0/mo | $200/mo | Free |
50K | $1140/mo | $0/mo | $100/mo | Free |
Может показаться, что более $1000 за 50к пользователей — это дорого. Но на самом деле, если вы не делаете соц. сеть и у вас продукт монетизируется — каждый пользователь приносит деньги. И лучше включить эту сумму в стоимость подписки, чем внедрять решение самостоятельно.
У AWS Cognito до 50 тысяч пользователей стоимость сервиса составляет $0, но стоит помнить, что вам придется платить за API.
У Firebase все полностью бесплатно, потому что у них Firebase Authentication попадает в категорию бесплатного сервиса.
Как принять окончательное решение
Помните, что если есть такая возможность, то всегда лучше выбрать облачный подход. Если вы являетесь агрегатором новостей, социальной сетью или крупным порталом — делайте агрегацию, а аутентификацию купите. Если же есть какие-то жесткие регуляции в компании, возможно вы банк или государственное учреждение, у вас может не быть выбора, и вам придется использовать open source вместе проприетарного решения. Если ничего из этого не подходит или если нужно сделать proof of concept — пишите решение самостоятельно.
26 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів