Подтвердить что ты не робот

Универсальный маршрутизатор Auth Redux & React Router

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

У меня есть компонент входа, который при отправке отправляет следующее действие:

export const loginUser = (creds) => {
  return dispatch => {

    dispatch(requestLogin(creds))

    return fetch('http://127.0.0.1:4000/api/login', {
      ...
    })
      .then(res => {
        dispatch(receiveLogin())
        browserHistory.push('/admin')
        ...
      })
      ...
  }
}

Действие receiveLogin обновляет флаг isAuthenticated в состоянии true. В моем защищенном маршруте есть следующий привязчик:

export default (state) => {
  return {
    path: '/',
    component: App,
    childRoutes: [
      {
        path: 'protected',
        component: Protected,
        ...
        onEnter(nextState, replaceState) {
          const loggedIn = //check state.isAuthenticated
          if (!loggedIn) {
            replaceState(null, 'login')
          }
        }
      }
    ]
  }
}

Как вы можете видеть, я передаю состояние в качестве аргумента. Это дает мне доступ к исходному состоянию как с сервера, так и с клиента. Однако после того, как мое действие для входа произойдет, очевидно, что hook onEnter все равно будет использовать начальное состояние.

То, что я хочу знать, - лучший способ получить текущее состояние после обновления флажка isAuthenticated и использовать его вместо моего байта onEnter. Или, мой подход полностью испорчен, и должен ли я делать это по-другому?

4b9b3361

Ответ 1

Я обнаружил, что использование перехватчиков onEnter не является лучшим подходом в моих приложениях для обработки этого типа логики auth и подключения к хранилищу redux.

Одна из (нескольких) подводных камней здесь заключается в том, что даже если вы могли бы войти в систему с вашего "защищенного" маршрута, если они должны были выйти из системы, находясь в "защищенном", они никогда не будут перенаправлены на "логин", t запускает onEnter.

Альтернативный подход заключается в использовании компонентов более высокого порядка, см. статью Dan Abramov об использовании их над mixins, и я нахожу их действительно полезными в этом контексте. Там было несколько gists/example repos, где их использовать, но я недавно создал библиотеку redux-auth-wrapper специально для этой цели. Его довольно новый, но я думаю, что это может быть полезно и позволяет избежать некоторых опасностей при неправильном использовании HOC для auth, что может привести к бесконечным циклам-перенаправлениям.

Идея использования HOC заключается в том, что это функция, которая при применении к компонентам каким-то образом расширяет функциональность. Пользователи redux, скорее всего, знакомы с connect для улучшения компонентов с подпиской на магазин.

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

Я также рассмотрю примеры аналогичной стратегии: https://github.com/joshgeller/react-redux-jwt-auth-example.

И вот пример, который использует onEnter для auth с некоторым обманом магазина, но я считаю, что он не будет обрабатывать описанный выше краевой случай: https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx.