2017-04-27 97 views
1

这里首先是我的代码:反应路由器V4认证令牌保持重定向到/

Routes.js:

import React from 'react'; 
import PropTypes from 'prop-types'; 
import { Redirect, Route } from 'react-router-dom'; 
import { PUBLIC_ROUTE, LOGIN_ROUTE } from './utils/constants'; 

const routes = ({ component: Component, ...rest }) => { 
    let { requireAuth, isAuthenticated } = rest; 

    if (!requireAuth) { 
     requireAuth = false; 
    } 

    // If user authenticated 
    if (isAuthenticated) { 
     // If page need auth 
     if (requireAuth === true) { 
      return (
       <Route {...rest} render={props => <Component {...props} />} /> 
      ); 
     } else if (requireAuth === 'partial') { // If the page is doesn't require auth but can't be access if auth true 
      return <Redirect to={PUBLIC_ROUTE} />; 
     } 

     // If page doesn't need auth 
     return <Route {...rest} render={props => <Component {...props} />} />; 
    } 

    // If user not authenticated // 

    // page doesn't require Auth 
    if (requireAuth === false || requireAuth === 'partial') { 
     return <Route {...rest} render={props => <Component {...props} />} />; 
    } 
    // If page require Auth redirect user to login routes 
    return (
     <Route 
      {...rest} 
      render={props => (
       <Redirect 
        to={{ 
         pathname: `${LOGIN_ROUTE}`, 
         state: { from: props.location }, 
        }} 
       /> 
      )} 
     /> 
    ); 
}; 

routes.propTypes = { 
    component: React.PropTypes.oneOfType([ 
     React.PropTypes.element, 
     React.PropTypes.func, 
    ]), 
}; 

export default routes; 

App.js:

const history = createHistory(); 

const mapStateToProps = state => { 
    const { auth, global } = state; 
    const { authenticated, user } = auth; 
    const { loading } = global; 

    return { authenticated, user, loading }; 
}; 

const reduxConnector = connect(mapStateToProps, { ping }); 

class App extends Component { 
    state = { 
     isAuthenticated: false, 
    }; 
    static propTypes = { 
     authenticated: PropTypes.bool.isRequired, 
    }; 

    componentWillReceiveProps(nextProps) { 
     this.setState({ isAuthenticated: nextProps.authenticated }); 
    } 

    render() { 
     const { authenticated, user, loading } = this.props; 
     const { isAuthenticated } = this.state; 

     if (loading) { 
      return (
       <div style={style.center}> 
        <MDSpinner /> 
       </div> 
      ); 
     } 

     return (
      <ConnectedRouter history={history}> 
       <div> 
        <NotificationsSystem theme={theme} /> 
        <Header isAuthenticated={isAuthenticated} user={user} /> 
        <NavMobile /> 
        <SideMenu /> 
        <Nav /> 

        <Switch> 
         <Routes 
          requireAuth={false} 
          isAuthenticated={isAuthenticated} 
          exact 
          path="/" 
          component={Welcome} 
         /> 

         <Routes 
          requireAuth={true} 
          isAuthenticated={isAuthenticated} 
          path="/point" 
          component={Point} 
         /> 

         <Routes 
          requireAuth="partial" 
          isAuthenticated={isAuthenticated} 
          path="/login" 
          component={Login} 
         /> 

         <Routes render={() => <h3>No Match</h3>} /> 
        </Switch> 
        <Footer /> 

       </div> 
      </ConnectedRouter> 
     ); 
    } 
} 

export default reduxConnector(App); 

Login.js:

import React from 'react'; 
import PropTypes from 'prop-types'; 
import { withRouter, Link, Redirect } from 'react-router-dom'; 
import { Field, reduxForm } from 'redux-form'; 
import { connect } from 'react-redux'; 
import cookie from 'react-cookie'; 

import { Headline, Section, renderField } from 'components'; 
import { ping } from 'redux/modules/auth'; 

function mapStateToProps(state) { 
    const { authenticated } = state.auth; 

    return { authenticated }; 
} 

const reduxConnector = connect(mapStateToProps, { ping }); 
const token = cookie.load('_t'); 

class Login extends React.Component { 
    static defaultProps = { 
     loggingIn: false, 
     authenticated: false, 
    }; 

    componentDidMount(){ 
     if(cookie.load('_t')){ 
      this.props.ping(); 
     } 
    } 

    render() { 
     const { handleSubmit } = this.props; 

     const { from } = this.props.location.state || { 
      from: { pathname: '/' }, 
     }; 


     if (this.props.authenticated) { 
      return <Redirect to={from} />; 
     } 

     return <div> 
       <Headline title="Login" /> 
      </div>; 
    } 
} 

export default withRouter(reduxConnector(reduxFormDecorator(Login))); 

这里是问题:

让我说我已经登录到我的应用程序。我想导航到/point(需要授权才能访问),应用程序将在检查令牌(​​)后redirect/login: 1.如果令牌有效:它会将我重定向回point页面。 2.如果令牌无效:它会将我重定向到login页面。

问题:

  1. 后检查和令牌是有效的,应用程序总是重定向到/。 我已经console.log my const {from}结果是{pathname: "/point", search: "", hash: "", state: undefined, key: undefined}。它永远不会返回到上一页(在这种情况下/point页)。

  2. 如果我访问'/'它永远不会重定向到登录,致电ping。我需要这个,因为我的头部显示用户全名。所以我需要设置状态为redux。

任何解决方案?

回答

0

首先,您应该了解Redirect在安装组件后会工作一次。您不能在重新渲染中对其进行中继。您可以改用history.push() API方法。第二,我不确定我是否正确理解了你的解决方案,但似乎你想重定向某处,只是为了设置一些数据到redux商店(找不到你在哪里调度redux动作)。如果这是真的,这是一个不好的做法。您可以在登录后在专用操作中执行此操作,而无需将此逻辑与任何组件关联,则不需要重定向。

+0

我想我明白了。将尝试实施它。 – ssuhat