在react路由器中,我们如何构建基于身份验证的路由?

时间:2017-04-16 02:42:12

标签: reactjs authentication redux react-router react-redux

在react路由器中,我们如何构建基于身份验证的路由?

假设我们希望某些路由需要特定的身份验证,让我们说authTypeA,以便访问,而某些路由需要更多身份验证,让我们一起说authTypeA,authTypeB,authTypeC。

那我们如何在反应路由器(v2)中制作这些?

2 个答案:

答案 0 :(得分:0)

const Routes = (
<Route path="/" component={App}>
  <Route component={requireAuth(['authenticated'], ['/trade'])}>
    <Route path="/dualview" component={TradingViewContainer} />
    <Route path="/marketdata" component={MarketDataContainer} />
  </Route>
  <Route path="/signin" component={SigninContainer} />
</Route>
);

我们可以使用HOC(高阶组件)来构建基于身份验证的路由,该路由在检查身份验证后管理访问路径。

在react router v2中,您可以在具有身份验证逻辑的高阶组件中定义。

export default function(strategies = [], greenRoute = []) {
  class Authentication extends Component {
    constructor() {
      super()
      this.state = { allGreen: true }
    }
    componentWillMount() { // When access the route with first time
      const { history, location } = this.props
      if (greenRoute.indexOf(location.pathname) === -1) {
        strategies.map((strategy) => {
          if (!this.props.auth[strategy]) {
            this.setState({ allGreen: false })
            history.replace(`signin?next=${location.pathname.slice(1)}`)
          }
        })
      }
    }
    componentWillUpdate(nextProps) {
      const { history, auth } = this.props
      if (greenRoute.indexOf(location.pathname) === -1) {
        strategies.map((strategy) => {
          if (!nextProps.auth[strategy]) {
            this.setState({ allGreen: false })
            alert(I18n.t('auth.needSignin'))
            history.replace(`signin?next=${location.pathname.slice(1)}`)
          }
        })
      }
    }
    shouldComponentUpdate(prevProps, prevState) {
      const { location } = this.props
      if (prevProps.location !== location) {
        return true;
      }
      for (var i = 0; i < strategies.length; i++) {
        return prevProps.auth[strategies[i]] !== this.props.auth[strategies[i]]
      }
    }
    render() {
      return this.state.allGreen ? this.props.children : (<div></div>)
    }
  }

  function mapStateToProps(state) {
    return {
      auth: state.auth
    }
  }

  return connect(mapStateToProps)(Authentication)
}

在上面的代码中,你可以建立一个逻辑,当this.state.allGreen为true时,然后渲染this.props.children你想要访问的组件。

在requireAuth组件(HOC)中, componentWillMount 将中断以访问需要身份验证的特定组件,并检查它是否具有身份验证状态,然后决定是否访问。

并且,当更改身份验证状态时,可以使用 componentWillUpdate ,以便拒绝访问组件。

shouldComponentUpdate 将用于表现。

此代码基于库react,react router,redux。

随意使用!

答案 1 :(得分:0)

在react-router中,您可以提供一个在进入路径之前运行的功能。在那里,您可以在出现问题时进行验证和重定向。检查此示例。希望它能回答你

 import React from 'react';
    import { IndexRoute, Route, Redirect } from 'react-router';
    import App from './App';
    import { getToken } from './main/services/cookie';
    import Navigation from './main/navigation/Navigation';
    import * as authenticationActions from './authentication/actions/authenticationActions';

    export default (store) => {

      const performAuth = async (nextState, replace, callback) => {
        const authenticated = store.getState().authentication.authenticated;
        const token = getToken();

        if (!authenticated) {
          await store.dispatch(authenticationActions.authenticate(token));
        }
        callback();
      };

      const requireAuth = (nextState, replace) => {
        const authenticated = store.getState().authentication.authenticated;
        if (!authenticated) {
          replace({ pathname: Navigation('login') });
        }
      };

      const checkAuth = (nextState, replace) => {
        const authenticated = store.getState().authentication.authenticated;
        if (authenticated) {
          replace({ pathname: Navigation('schedule') });
        }
      };

  const languages = ['en', 'fr'];

  return (
    <Route onEnter={performAuth}>
      <Route path="/" component={App} >
        <IndexRoute component={Login} onEnter={checkAuth} />
            <Route path={Navigation('login', language)} component={Login} onEnter={checkAuth} />
            <Route path={Navigation('schedule', language)} component={PersonalSchedule} onEnter={requireAuth} />
            <Route path={Navigation('profile', language)} component={Profile} onEnter={requireAuth} />
      </Route>
      <Redirect from="*" to="/" />
    </Route>
  );
};