react редирект после авторизации
Автоматическое перенаправление после входа в систему с react-router
Я хотел создать вход в Facebook в мой react / react-маршрутизатор / поток приложение. У меня есть слушатель, зарегистрированный в событии входа в систему, и хотел бы перенаправить пользователя на ‘/dashboard’ если они вошли в систему. Как я могу это сделать? location.push работал не очень хорошо, за исключением полной перезагрузки страницы.
7 ответов
реагирует маршрутизатор v0.13
на Router экземпляр вернулся из Router.create может передаваться (или, если внутри компонента React, вы можете получить его из контекст объекта), и содержит методы как transitionTo что можно использовать для перехода на новый маршрут.
реагировать маршрутизатор v3
реагировать маршрутизатор v4
теперь мы можем использовать компонент в маршрутизаторе React V4.
визуализация перейти на новое место. Новое расположение переопределит текущее местоположение в стеке истории, например перенаправление на стороне сервера.
реагировать маршрутизатор v2
хотя на вопрос уже дан ответ, я думаю, что важно опубликовать решение, которое сработало для меня, поскольку оно не было охвачено ни одним из решений, приведенных здесь.
во-первых, я использую контекст маршрутизатора на моем LoginForm компонент
после этого я могу получить доступ к router объект внутри моей LoginForm компонент
PS: работа над версией React-router 2.6.0
реагировать маршрутизатор v3
навигация вне компонентов
создать приложение с маршрутизатором, как это
реагирует маршрутизатор v4.2.0
Я использую реагировать-16.2.0 & React-router-4.2.0
и я получаю решение этим кодом this.props.history.push(«/»);
мой рабочий код:
Я также пытался return но к несчастью, это не работает для меня.
навигация внутри компоненты
вы должны использовать withRouter декоратор, когда необходимо перенаправить внутри компонента. Декоратор использует контекст вместо вас.
HoC (компонент более высокого порядка), который обертывает другой компонент для повышения его реквизит с реквизитом маршрутизатора.
Pass в вашем компоненте и он возвратит завернутый компонент.
вы можете точно указать роутер как опору для компонента обертке переопределите объект маршрутизатора из контекста.
Подробно о React Router. Часть 3— редиректы, передача props компоненту роута и вложенные роуты +бонус
В этой серии статей вы подробно и доходчиво узнаете о том, как работает Router в React, как его можно использовать и другие интересные фишки этого функционала. Это завершающая часть, в ней будет рассказано о передаче пропсов компоненту роута, редиректах и вложенных роутах. + бонус, стилизация активных элементов навигации.
p.s статья описывает самый распространенную версию роутера на данный момент. 6я версия сейчас находится в альфе и имеет кардинально другой синтаксис.
Передаём пропсы компоненту роута
Мы видели несколько примеров и рабочих кейсов в React роутере. Один из них это передача пропсов напрямую компоненту самого роута.
В React-router это делается очень легко. Давайте создадим новый роут для передачи props его компоненту.
Прямо сейчас мы добавили компонент и новую страницу. Давайте передарим пропс title уже самой странице.
Есть два способа это сделать. Первый очень простой.
Передаём функцию как пропс компонента в компоненте роута
Эта штука сработает, но такой подход не рекомендуется применять с роутером. Почему? Сейчас объясню.
Под капотом React использует React.createElement для рендеринга компонента, переданного пропсу компонента. Если мы передадим ему функцию, то он создаст новый компонент при каждом рендере, вместо того, чтобы просто обновить уже существующий компонент.
В маленьких приложениях с довольно несложными страницами, это не будет влиять на производительность. Но для больших приложений с множественным изменением состояния на странице, это значительно снизит производительность из-за необязательных циклов ре-рендеринга.
Вот это уже рекомендуемый способ передачи самих пропсов в React роутере.
Это очень просто. Если вы хотите увидеть весь пример, то проверьте его тут.
Редиректим роуты
В основном редиректы используют при проверке пользователей на авторизацию, если пользователь не авторизован, то его перенаправит на соответствующую страницу.
Давайте посмотрим на простой пример того, как он работает. Давайте создадим простую страницу, которая перенаправит на другую страницу основываясь на заданных условиях.
Давайте перенаправим с /old-route на /new-route
Простой пример редиректа
Добавляем роут редиректа в наш пример.
Сейчас мы создадим два URL.
Тут вы увидите, что старая ссылка редиректит на новую ссылку и тут же показывает его в браузере.
Редирект посложнее, основанный на пропсах
Давайте сначала сделаем страничку.
Давайте укажем роут для страниц Auth и Dashboard :
Вложенные роуты и контент
До этого мы видели простые примеры работы с реакт роутером. А сейчас мы разберемся с тем, как работать с вложенными роутами. Перед тем как углубиться в них давайте поймем, что же это такое?
Примеры вложенных роутов
Этот роут показывает всех пользователей.
Вложение первого уровня:
Эти примеры роутов показывают конкретного пользователя. Param и miguel это userId используемые для получения данных о конкретных пользователях.
Вложение второго уровня:
www.example.com/user/param/employer Этот роут получает простую информацию о пользователе и также информацию о его работодателе. Так что можно сказать, что это вложенные роуты. А вложения второго уровня уже зависят от параметров вложения первого уровня ( userId: param )
Давайте начнем с конкретного примера. Мы собираемся показать пользователей и затем вывести детальную информацию о них.
Вложенные роуты в React Router
Для примера мы возьмем вот эти данные:
В этом примере есть несколько пользователей и каждый из них имеет разное количество вложенных табов, в каждом из которых есть имя и контент, который мы покажем.
Используя эти данные мы создадим эти роуты:
Вложение первого уровня:
Вложения второго уровня:
Показываем вложения первого уровня
Тут мы пробегаемся по всем данным пользователей и показываем ссылку на каждого пользователя с данными о нем.
Компонент UserPage покажет простую информацию о конкретном пользователе.
Показываем вложенные роуты как табы
Тут мы создаем вложенные роуты, используя информацию для табов у каждого пользователя.
match.path уже выдаёт нам имя пути. Его мы будем использовать для указания вложенной схемы роута.
Именно поэтому match.url находится в Link, а match.path используется в определении роута.
Находим таб в наших данных, используя оба параметра
Показываем информацию таба
Следовательно, мы показали вложенные роуты и вложенный контент в этом примере.
Посмотрим пример в действии.
БОНУС: Используем для указания того, какой элемент активен в панели навигации
Вы можете также импортировать и :
Оба они компилируются в html код, как тут:
Может показаться, что основной их функционал одинаков. Так зачем же нам тогда оба? А затем, что идёт вместе с дополнительным атрибутом стилизации, который позволяет нам стилизовать по особенному именно активную ссылку.
CSS селекторы описанные ниже, рендерят линию подчеркивания в тех случаях, когда мы наводим на ссылку и когда она открыта и активна.
Email подписка!
Automatic redirect after login with react-router
I wanted to build a Facebook login into my react/react-router/flux application. I have a listener registered on the login event and would like to redirect the user to ‘/dashboard’ if they are logged in. How can I do that? location.push didn’t work very well, except after reloading the page completely.
8 Answers 8
Now we can use the component in React Router v4.
Rendering a will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects.
The Router instance returned from Router.create can be passed around (or, if inside a React component, you can get it from the context object), and contains methods like transitionTo that you can use to transition to a new route.
Even though the question is already answered, I think it’s relevant to post the solution that worked for me, since it wasn’t covered in any of the solutions given here.
First, I’m using the router context on my LoginForm component
After that, I can access the router object inside my LoginForm component
PS: working on React-router version 2.6.0
Navigating Outside of Components
create your app with Router like this
Somewhere like a Redux middleware or Flux action:
I am using React-16.2.0 & React-router-4.2.0
And I get solution by this code this.props.history.push(«/»);
My working code:
I was also try by return But unlucky, this not working for me.
React router v5 using hooks
These steps are for authorisation redirect. But can be used for login/logout redirection also.
The accepts to prop as a string or an object. We can utilise the object to pass the redirection path after login/logout using hooks easily.
Get the pathname of url from where the is called using useLocation()
const
In the to prop of pass in the following object:
Я пытаюсь выполнить простое перенаправление с React Router после того, как мой пользователь успешно вошел в систему (внутри Login.js), и не позволяет пользователю повторно посетить страницу входа (внутри index.js).
В Login.js у меня есть onSubmit=
В index.js у меня есть условие, которое проверяет, вошел ли пользователь в систему или нет, и (плохо) предупреждает пользователя о том, почему он не может посетить нужную страницу. Я видел это в видео на Youtube, но не уверен, что это лучший способ получить желаемый эффект.
В настоящее время, когда я вхожу в систему успешно, предупреждение You can’t login if you are logged in! отключено, но я, очевидно, не хочу, чтобы предупреждение исчезло сразу после успешного входа в систему, я хочу, чтобы перенаправление инициировалось первым. Если я поменяю их в скобках, React выдаст ошибку.
Компонент Login.js :
Компонент index.js :
App.js :
3 ответа
Чтобы решить вашу проблему, вы должны создать отдельные компоненты для Login / Register и сделать оповещения и перенаправления в зависимости от пользователя. Вам понадобится Компонент высшего порядка с именем withRouter из react-router lib.
А затем используйте его в своем Routes так:
Кроме того, я советую вам использовать аутентификацию HoC для ваших частных маршрутов, которая недоступна без аутентификации.
Я бы предпочел использовать новый контекстный API для совместного использования такой сущности, как пользователь, локализация и т. Д., Поэтому вот пример того, как сделать PrivateRoute с помощью React Context API.
App.js
И тогда вы можете использовать PrivateRoute вместо Route в случае, если вы не хотите показывать страницу без аутентификации.
React.js: собираем с нуля изоморфное / универсальное приложение. Часть 3: добавляем авторизацию и обмен данными с API
Это третья и заключительная часть статьи про разработку изоморфного React.js приложения с нуля. Части первая и вторая.
1. Добавляем redux-dev-tools
Это очень удобная библиотека, упрощающая процесс разработки. С ее помощью вы сможете в режиме реального времени видеть содержимое глобального состояния, а также его изменения. Дополнительно redux-dev-tools позволяет «откатывать» последние изменения глобального состояния, что удобно в процессе тестирования и отладки. Нам же она добавит наглядности и сделает процесс обучения более интерактивным и прозрачным.
1.1. Устанавливаем необходимые пакеты
1.2. Реализуем компонент, отвечающий за рендеринг панели redux-dev-tools
src/components/DevTools/DevTools.jsx
src/components/DevTools/index.js
1.3. «Причешем» rootReducer
Во второй части мы поместили создание корневого редьюсера в configureStore, что не совсем правильно, так как это не его зона ответственности. Сделаем небольшой рефакторинг и перенесем его в redux/reducers/index.js.
redux/reducers/index.js
Из документации redux-dev-tools следует, что нам необходимо внести изменения в configureStore. Вспомним, что инструменты redux-dev-tools нам нужны только для разработки, поэтому повторим маневр, описанный ранее:
src/redux/configureStore.prod.js
Реализация configureStore.dev.js с DevTools и поддержкой hot-reload.
src/redux/configureStore.dev.js
Точка входа configureStore
src/redux/configureStore.js
Все готово! Перезапускаем webpack-dev-server и nodemon, открываем браузер и видим, что справа появилась панель, которая отражает содержимое глобального состояния. Теперь откроем страницу со счетчиками и понажимаем на ReduxCounter. Одновременно с каждым кликом мы видим, как в очередь redux поступают действия и глобальное состояние изменяется. Нажав на Revert, мы сможем отменить последнее действие, а нажав на Commit — утвердить все действия и очистить текущую очередь команд.
Примечание: после добавления redux-dev-tools, возможно, вы увидите сообщение в консоли: «React attempted to reuse markup in a container but the checksum was invalid. «. Это означает, что серверная и клиентская часть приложения рендерят неодинаковый контент. Это очень плохо, и в своих приложениях таких ситуаций следует избегать. Однако, в данном случае виновником является redux-dev-tools, который мы все равно в продуктиве использовать не будем, поэтому можно сделать исключение и спокойно проигнорировать сообщение о проблеме.
Update: спасибо пользователям gialdeyn и Lerayne, починить SSR с redux-dev-tools можно следующим способом
src/server.js
src/client.js
2. Добавляем новую функциональность
Реализуем следующий сценарий
Это достаточно объемная задача. Чтобы сфокусироваться на отдельных ее частях, сначала реализуем пункты 1,2 и 5, а для 3 и 4 сделаем заглушку.
2.1. Добавляем действия
После клика по кнопке «Запросить время» мы должны последовательно:
Здесь каждое действие мы оформляем в виде небольшой функции, которая будет изменять глобальное состояние, а timeRequest — комбинация этих функций, которая целиком описывает наш сценарий. Именно ее мы и будем вызывать из нашего компонента.
2.2. Обновляем код страницы со временем
Добавим кнопку react-bootstrap-button-loader с поддержкой индикатора загрузки на страницу TimePage и научим ее вызывать функцию timeRequest по клику.
Устанавливаем пакет react-bootstrap-button-loader
Добавляем кнопку и обработчик кликов
src/components/TimePage/TimePage.jsx
Заметим, что нам пришлось использовать connect из react-redux, чтобы у нашей кнопки был доступ к функции dispatch для изменения глобального состояния.
Самое время посмотреть на результаты трудов: откроем страницу «Время» в браузере, нажмем на кнопку «Запросить». Интерфейс пока еще ничего не делает, но в redux-dev-tools мы теперь видим, как запускаются actions, которые мы совсем недавно реализовали.
Настало время оживить интерфейс. Начнем с реализации логики для обновления глобального состояния
2.3. Реализуем редьюсер
src/redux/reducers/timeReducer.js
Важный момент, о котором нельзя забывать: по спецификации redux мы не имеем права изменять переданное нам состояние и обязаны возвращать либо его же, либо новый объект. Для формирования нового объекта я использую Object.assign, который берет исходный объект и применяет к нему нужные мне изменения.
Хорошо, теперь добавим новый редьюсер в корневой редьюсер.
src/redux/reducers/index.js
Снова откроем браузер и, предварительно очистив очередь redux-dev-tools, покликаем по кнопке «Запросить». Интерфейс все еще не обновляется, но теперь наши actions изменяют глобальное состояние согласно коду нашего редьюсера, а это значит, что «под капотом» вся логика работает как надо. Дело за малым — «оживим» интерфейс.
2.4. Обновляем код страницы «Время»
src/components/TimePage/TimePage.jsx
Переходим в браузер, снова нажимаем на кнопку «Запросить» и убеждаемся, что все работает согласно нашему сценарию.
Настало время заменить заглушку на настощий backend.
3. Добавляем взаимодействие с backend и авторизацию
Со стороны клиентской части нам многое предстоит сделать:
3.1. Передаем глобальное состояние
Механизм очень простой:
src/server.js
src/client.js
Как видно из кода, глобальное состояние я передаю в переменной REDUX_INITIAL_STATE.
3.2. Добавляем авторизацию
Примечание: мы используем redux-oauth для изоморфного сценария, но она также поддерживает и client-side only. Примеры конфигурации для различных случаев и демо можно найти на сайте библиотеки.
Примечание 2: redux-oauth использует cookie для авторизации, так как механизм local storage не подходит для изоморфного сценария.
Активируем плагин cookieParser для express
src/server.js
Настраиваем redux-oauth для серверной части приложения
src/server.js
Здесь происходит много интересного:
Согласно документации, нам также необходимо добавить редьюсер redux-oauth в корневой редьюсер.
src/redux/reducers/index.js
3.3. Заменяем заглушку в timeActions.js
src/redux/actions/timeActions.js
Функция fetch из redux-oauth — это расширенная функция из пакета isomorphic-fetch. Согласно документации, ее необходимо вызывать через dispatch, так как в этом случае у нее будет доступ к глобальному состоянию, из которого она сможет считать авторизационный токен и отправить его вместе с запросом. Если функцию fetch использовать для произвольного HTTP-запроса, а не запроса к API, то авторизационный токен использован не будет, то есть алгоритм ее выполнения на 100% совпадет с алгоритмом выполнения isomorphic-fetch.
Примечание: isomorphic-fetch — это библиотека, которая умеет делать HTTP-запросы как из браузера, так и из Node окружения.
Откроем браузер и еще раз нажмем на кнопку «Запросить» страницы «Время». Что ж, мы больше не видим текущий timestamp, зато в redux-dev-tools появилась информация о 401 ошибке. Неудивительно, ведь мы должны быть авторизованы, чтобы API нам что-то вернул.
3.4. Добавим кнопки «Войти» и «Выйти»
Как правило, авторизованный пользователь имеет больше возможностей по работе с системой, чем гость, иначе какой же смысл в авторизации?
С технической точки зрения это означает, что многие компоненты могут выглядеть и вести себя по-разному в зависимости от того, зашел пользователь в систему или нет.
Я являюсь ярым сторонником принципа DRY (don’t repeat yourself), поэтому напишем небольшой хелпер.
src/redux/models/user.js
Реализуем кнопку «Войти в систему»
src/components/AuthButtons/OAuthButton.jsx
Эта кнопка будет отображаться, только если пользователь еще не вошел в систему.
Реализуем кнопку «Выйти из системы»
src/components/AuthButtons/SignOutButton.jsx
Эта кнопка будет отображаться, только если пользователь уже вошел в систему.
src/components/AuthButtons/index.js
Я добавлю авторизацию на страницу HelloWorldPage.
src/components/HelloWorldPage/HelloWorldPage.jsx
Настало время насладиться результатами нашего труда. Нажимаем на кнопку «Войти», используем свой github аккаунт для авторизации и… мы в системе! Кнопка «Войти» исчезла, зато появилась кнопка «Выйти». Проверим, что сессия сохраняется, для этого перезагрузим страницу. Кнопка «Выйти» не исчезла, а в redux-dev-tools можно найти информацию о пользователе. Отлично! Пока все работает. Переходим на страницу «Время», нажимаем на кнопку «Запросить» и видим, что timestamp отобразился — это сервер вернул нам данные.
На этом можно было бы закончить, но нам нужно «отшлифовать» наше приложение.
4. «Шлифуем» приложение
Итак, что можно улучшить:
4.1. Убираем ссылки к недоступным страницам
src/components/App/App.jsx
Открываем браузер и видим, что ссылка на страницу «Время» все еще доступна, переходим на страницу HelloWorldPage, нажимаем на кнопку «Выйти» — и ссылка пропала.
4.2. Ограничиваем доступ к защищенным страницам
Как мы помним, за соответствие между URL и страницей, которую нужно отрендерить отвечает библиотека react-router, а конфигурация путей находится в файле routes.jsx. Нам нужно добавить следующую логику: если пользователь неавторизован и запросил защищенную страницу, то перенаправим его на HelloWorldPage.
Для получения информации о пользователе нам необходимо передать в routes.jsx ссылку на хранилище глобального состояния.
src/server.js
src/client.js
src/routes.jsx
Примечание: в функции requireAuth используется setTimeout с нулевой задержкой, что на первый взгляд лишено смысла. Это сделано специально, так как позволяет обойти баг в одном из популярных браузеров.
4.3. Очищаем пользовательские данные из глобального состояния
src/redux/reducers/timeReducer.js
Если поступит action SIGN_OUT, то все данные редьюсера timeReducer будут заменены на initialState, то есть на значения по умолчанию. Этот же прием необходимо реализовать для всех других редьюсеров, которые содержат пользовательские данные.
5. Бонус: Server-Side API Requests
Библиотека redux-oauth поддерживает Server Side API requests, то есть в процессе рендеринга сервер может сам обратиться к API за данными. Это имеет множество преимуществ:
Примечание: да, поисковики не будут авторизовываться, но некоторые сервисы API смогут возвращать данные и для неавторизованных пользователей с некоторыми ограничениями. redux-oauth подойдет и для таких сценариев.
Реализуем небольшой Proof of Concept.
Добавим запрос к API в серверную часть нашего приложения
src/server.js
После того, как функция initialize из redux-oauth обратится к backend, проверит авторизационный токен и получит данные о пользователе, мы выполним запрос timeRequest на стороне сервера. После его выполнения мы отрендерим контент и отдадим ответ пользователю.
Откроем браузер, авторизуемся при необходимости, перейдем на страницу «Время» и нажмем F5. Мы должны увидеть timestamp, хотя кнопку «Запросить» никто не нажимал. Если открыть Dev Tools браузера, вкладку Network и повторить эксперимент, то мы увидим, что запроса к API из клиента не было. Это подтверждает, что вся работа была сделана на стороне сервера.
Внесем последнее небольшое улучшение в наш проект: будем делать запрос к API только в том случае, если пользователь авторизован.
src/redux/actions/timeActions.js
Как мы видим, внутри возвращаемой функции мы можем получить доступ к актуальному глобальному состоянию посредством вызова функции getState, которая будет передана вторым аргументом. Об этом далеко не все знают, а это очень полезная возможность.
6. Вместо заключения
Вот и подошел к концу цикл статей о веб-приложении на React.js с нуля. Искренне надеюсь, что он был вам полезен!
С удовольствием отвечу на ваши вопросы в комментариях, а также принимаю запросы на темы для следующих статей.