Разделение доступа
ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в telegram канале или twitter
На канале так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, присоединяйтесь!
Разделение доступа
В данном разделе, по шагам будет разобран вход на сайт в качестве администратора. Следовательно, мы сделаем недоступным для посещения адрес localhost:3000/admin
, а так же рассмотрим редирект на "главную" или в "админку" после ввода логина.
Создадим страницу логина.
В качестве "сервера для авторизации", будем использовать localStorage.
Алгоритм простой: вводится логин - кладется в localStorage.
src/components/Login/index.js
src/routes.js
src/containers/App/index.js
Напоминаю: несмотря на то, что ссылка появилась в шапке (hot-reload работает для компонента <App />
), страницу все равно нужно перезагрузить (так как hot-reload не работает для обновления списка роутов).
Если ввести новый "логин" - старый перетирается. Данное допущение сейчас не мешает нам проверить работоспособность, а наоборот облегчает проверку.
Нам необходимо закрыть доступ "не админам", для этого потребуется разобрать "события", которые возникают в процессе изменений URL'a.
onEnter, onLeave
Предлагаю добавить слово "хук" в словарь. По-моему, хук, не что иное как "действие на событие".
Итак, есть возможность использовать хуки на события onLeave и onEnter. По названию понятно: onLeave возникает, когда "роут покинут", а onEnter - в момент "захожу на роут".
Представьте адрес:
react-site.com/profile/photos/
его "роутер-реализацию": (не стоит так говорить в приличном месте)
/ + profile + photos
и его реализацию компонентами:
<App /> + <Profile /> + <Photos />
Представьте, что вы будучи на странице с фото, кликнули на ссылку для перехода на главную страницу. Произойдет:
onLeave на
/profile/photos
onLeave на
/profile
onEnter на
/
И обратная ситуация: вы находитесь на главной, и решили перейти в раздел фото:
onLeave на
/
onEnter на
/profile
onEnter на
/profile/photos
Вернемся к "хукам".
Добавьте в routes.js функцию checkLogin и непосредственно сам хук.
src/routes.js
Теперь если вы залогинетесь как admin - в консоли браузера вас "пропустят". Причем, заметьте, хук сработает при вводе url напрямую в строке ввода адреса + enter, либо если вы кликнете по ссылке. Так же, если вы уже находитесь в разделе admin и попробуете кликнуть на ссылку "Админка" - onEnter не произойдет, а следовательно и хук не сработает. Кажется, разработчики react-router'a постарались на славу.
На всякий случай, напоминаю, что очистить localStorage можно командой localStorage.clear()
У хука есть полезные аргументы - nextState, replace, callback. Нам понадобится replace. На пару слов подробнее можно прочитать в офф.документации.
Перепишем функцию checkLogin
src/routes.js
Попробуйте сейчас залогиниться под другим именем: вы не сможете войти на страницу /admin, независимо от того введете ли вы адрес и нажмете enter, или кликните по ссылке.
Страницу API Reference настоятельно рекомендую добавить в закладки.
Использование static method в качестве хука на onEnter
Наш код работает, но функция checkLogin, как будто мешается в файле с роутами. Может быть вынести ее в отдельный файл? А вы знаете, есть еще одно интересное решение: использовать static метод класса Admin.
src/components/Admin/index.js
Исправим routes.js (привожу полный листинг)
src/routes.js
Все, теперь с чистой совестью можете приступать к задачке на повторение.
Задача: если пользователь ввел admin - после нажатия кнопки "Войти" - направить его на /admin, иначе на /
Подсказка #1: Если данная задача вызвала у вас трудность, прочитайте еще раз предыдущую главу.
Решение:
src/components/Login/index.js
Итого: мы познакомились с возможностью "вклиниваться" в процесс роутинга. Разобрали рабочую ситуацию: как ограничить доступ юзеру в раздел администратора. Закрепили знания по программной навигации.
Исходный код на данный момент.
Last updated