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

Добавить аутентификацию в ваше приложение не так уж сложно, хотя есть несколько способов реализовать логику. Многие библиотеки маршрутизации поддерживают хуки навигации по маршруту, которые проверяют, вошел ли пользователь в систему, но альтернативный метод, подробно описанный ниже, использует компоненты React для структурирования вашего приложения на разделы «вошел в систему» ​​и «вышел из системы».

Чего мы хотим достичь

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

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

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

Первый подход: крючки для маршрутизации

В зависимости от библиотеки, которую вы используете для маршрутизации, такой как response-router или react-native-router-flux, у вас может быть встроенная поддержка обратных вызовов навигации по маршруту. React Router, например, позволяет вам определять свойство onEnter на маршруте, которое представляет собой обратный вызов, который запускается до того, как пользователь войдет в запрошенный им маршрут.

Свойство onEnter позволяет вам проверить запрошенный маршрут и отправить пользователя на другой маршрут на основе определенных вами параметров. См. Определение маршрута в строке 18 ниже:

Свойство onEnter в маршруте `/ checkout` означает, что, когда пользователь переходит на страницу оформления заказа, соответствующая функция requireAuth срабатывает и проверяет, вошел ли пользователь в систему. Если пользователь не вошел в систему, они будет перенаправлен на страницу `/ login`.

Однако у этого рабочего процесса есть некоторые ограничения. Один из них - это повторение добавления свойства onEnter к каждому маршруту, требующему аутентификации. Другое ограничение более серьезное. Использование шаблона onEnter указывает на то, что ваша функция requireAuth сможет ответить на вопрос «Этот пользователь вошел в систему?» Если вы работаете в приложении Redux и сохраняете ответ на этот вопрос в дереве состояний вашего приложения, может быть непросто (или вообще невозможно) получить этот ответ от функции, которая не связана с состоянием вашего приложения и не иметь доступа к функции диспетчеризации Redux.

Альтернативный подход

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

EnsureLoggedInContainer - это компонент Route без свойства path, но он ведет себя как любой другой компонент React. Поскольку EnsureLoggedInContainer является оболочкой для маршрутов проверки и учетных записей, любая логика, которую мы храним внутри EnsureLoggedInContainer, будет выполняться раньше, чем ее дочерние элементы.

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

Необходимая логика

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

EnsureLoggedInContainer

Задача EnsureLoggedInContainer состоит в том, чтобы прослушивать навигацию по вложенному маршруту и ​​гарантировать, что пользователь вошел в систему. Если пользователь вошел в систему, компонент ничего не делает и просто отображает своих дочерних элементов (запрошенный маршрут ). Если пользователь не вошел в систему, EnsureLoggedInConatainer должен записать текущий URL-адрес для последующего перенаправления, а затем направить пользователей на страницу входа.

Этот контейнер должен извлечь из глобального дерева состояний два фрагмента данных: текущее состояние входа в систему и текущий URL-адрес / путь. В этом примере используется React Router, но другие платформы (например, React Native) или другие библиотеки маршрутизации должны иметь аналогичные методы для поиска текущего URL / пути.

Одно важное предостережение: для простоты мы предполагаем, что состояние входа пользователя доступно в глобальном дереве состояний по адресу `state.loggedIn`. Определение того, зарегистрирован ли пользователь или нет, является уникальной особенностью каждого приложения и может зависеть от множества различных факторов, таких как наличие определенного файла cookie или значения, отправленного с вашего сервера. Мы не будем касаться этой темы в этом уроке.

Компонент приложения

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

Как и EnsureLoggedInContainer, этому контейнеру нужны два фрагмента данных из глобального дерева состояний. Один - это текущее состояние входа в систему, а другой - URL-адрес для перенаправления при входе пользователя в систему.

Поскольку текущее состояние входа является свойством компонента App, вы будете предупреждены об изменениях значения свойства с помощью методов React componentWillUpdate и / или componentDidUpdate.

Ниже мы определяем метод componentDidUpdate, который вызывается при изменении свойства. Если пользователь входит в систему, мы перенаправляем на ранее установленный URL-адрес перенаправления. Также легко определить, когда пользователь выходит из системы, если вы хотите перенаправить пользователей в корень вашего приложения, как только это произойдет.

Заключение

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