Кастомизированная страница логина на Auth0 на базе React

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Почему Auth0?

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

Auth0 предоставляет удобные UI компоненты для получения идентификационных данных - виджеты для входа, регистрации, восстановления пароля. Данные виджеты включают также возможности логина с помощью сторонних сервисов - вход через аккаунт Google, Microsoft, GitHub и многие другие.

Виджет интуитивен и удобен в использовании. Он уже стал стандартом и, можно сказать, лицом технологии Single Sign-On.

Уникальный логин с помощью Customize Login Page

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

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

Для данных случаев у Auth0 имеется решение - Customize Login Page. В данном разделе настроек своей аппликации в Auth0 вы можете определить html страницу, которая будет показана вместо виджета Auth0 на его уникальном для вас адресе. Auth0 предоставляет два базовых шаблона, содержащих html теги элементов и соответствующий js скрипт для них. Этого достаточно, чтобы принять данные от пользователя, отправить запрос на аутентификацию и при положительном ответе осуществить редирект обратно на вашу аппликацию.

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

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

Один скрипт отрисовывает всю страницу. Страница приходит с домейна Auth0, но ее структура и логика - в руках разработчика
Один скрипт отрисовывает всю страницу. Страница приходит с домейна Auth0, но ее структура и логика - в руках разработчика

Как настроить кастомизированный логин?

О том, как настроить админку в Auth0 предлагаю почитать вот здесь: https://habr.com/ru/company/timeweb/blog/598727/

Рабочий образец можно посмотреть вот здесь: https://github.com/IvanovaNataly/auth-custom-login

Проект построен на react с помощью vite и mui, то есть его первые пакеты загружаем так:

npm create vite@latest
npm i @mui/material

В админке Auth0 переходим на вкладку Branding, затем на Universal Login, находим Advanced Options и далее вкладку Login. На этой странице активируем тогл Customize Login Page и добавляем следующий html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script>
var config = encodeURIComponent(window.atob('@configg@@'));
</script>
<script src="https://[your_domain]/dist/assets/index.js"></script>
</body>
</html>
Customize Login Page in Auth0
Customize Login Page in Auth0

Это та страница, которая будет отрисована при переходе на уникальный URI для аутентификации в рамках Auth0. Она содержит в себе:

1. корневой элемент, на котором наша реактовская аппликация построит страницу.

2. скрипт с плейсхолдером <@configg@@>. В момент поднятия страницы сервис Auth0 заменяет этот плейсхолдер на объект, содержащий все параметры, необходимые для запроса об аутентификации и последующего формирования токенов и кукис. Впоследствии мы воспользуемся этим объектом уже на нашей поднятой странице.

3. ссылку на скрипт, который по существу и является нашей скомпилированной аппликацией. Ссылка остается постоянной, содержание скрипта может изменяться в процессе разработки ;-)

Внутри нашего реактовского проекта основной рабочей компонентой является LoginForm. Она содержит в себе:

1. форму - компонент Box (mui), который рендерится как тэг <form> и запускает метод handleSubmit.

2. два текстовых поля ввода - компоненты TextField (mui), которые запускают методы handleChange & handleBlur, а также показывают ошибки.

3. кнопку - компонент Button (mui), которая неактивна до тех пор, пока не будет пройдена первичная валидация на стороне клиента.

При вводе имени и пароля в соответствующие поля формы с помощью методов handleChange, handleBlur, handleError осуществляется первичная валидация. При получении допустимых значений кнопка становится активной, и тогда с помощью метода requestLogin можно послать запрос на аутентификацию на сервер.

Параметры данного запроса формируются с помощью библиотеки auth0-js, поэтому добавляем ее в проект:

npm i auth-js

При запуске компоненты она обращается к объекту config, который мы получили в первом тэге <script> нашего статического html документа.

Далее проводим декодировку объекта:

const config = JSON.parse(decodeURIComponent(window.config));

Формируем параметры нашего локального инстанса auth0:

const params = Object.assign({
overrides: {
__tenant: config.auth0Tenant,
__token_issuer: config.authorizationServer.issuer
},
domain: config.auth0Domain,
clientID: config.clientID,
redirectUri: config.callbackURL,
responseType: 'code'
}, config.internalOptions);

И далее запускаем его:

const webAuth = new auth0.WebAuth(params);

При отправке формы на сервер метод requestLogin обращается к локальному инстансу auth0, вызывает его метод login с аргументами в виде способа авторизации (realm) и данных пользователя (username & password).

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

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

Вуаля, авторизация пользователя завершена, он может успешно разлогиниться и отдохнуть )))

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

Прим.прим.: в проекте для стилей использована библиотека @emotion, с которой по умолчанию работает mui. Однако в отдельной ветке feature/css есть вариант с простым css. В случае использования его, нужно в статической странице после ссылки на скрипт js, добавить линк на скомпилированный файл css.

Источник: https://habr.com/ru/post/722734/


Интересные статьи

Интересные статьи

React - это универсальная и гибкая библиотека, которую можно использовать для создания всего, от огромных SPA (Одностраничные приложения) до компактных подключаемых модулей. Однако создание React прое...
Я люблю сталкиваться с трудностями. Но с такими, которые можно решить, подумать над интересным решением, подобрать технологию. Люблю быть в потоке, а после решения чувствую себя настоящим профессионал...
Примерно 1-1,5 года назад Spring Webflux был на хайпе. Практически на любой Java-конференции можно было встретить доклады по Webflux, реактивному программированию, где-то даже про...
Тема статьи навеяна результатами наблюдений за методикой создания шаблонов различными разработчиками, чьи проекты попадали мне на поддержку. Порой разобраться в, казалось бы, такой простой сущности ка...
Мы публикуем видео с прошедшего мероприятия. Приятного просмотра.