2017-04-27 54 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にアクセスする必要があります(アクセスするには認証が必要です)。〜/loginのトークンを確認した後、 にアクセスします。1.トークンが有効な場合は、pointページに戻ります。 2.トークンが無効な場合は、loginページにリダイレクトされます。

問題:

  1. チェックし、トークンの後には、アプリが常に/にリダイレクトする、有効です。 console.log私のconst {from}の結果は{pathname: "/point", search: "", hash: "", state: undefined, key: undefined}です。前のページに戻ることはありません(この場合は/pointページ)。

  2. 私は '/'にアクセスすると、ログインするようにリダイレクトすることはありません。pingに電話してください。ユーザーのフルネームを示すヘッダーがあるので、これが必要です。だから私は還元するように状態を設定する必要があります。

答えて

0

最初に、Redirectがコンポーネントのマウント後に一度動作することを理解する必要があります。あなたは再レンダリングの中でそれを中継することはできません。代わりにhistory.push() APIメソッドを使用することができます。

第二に、私はあなたが解決策を正しく理解しているかどうかはわかりませんが、reduxストアにデータを設定するためにどこかにリダイレクトしたいと思うようです(還元アクションをディスパッチしているところは見つかりません)。それが本当なら、それは悪い習慣です。ログイン後に専用のアクションで実行することができます。このロジックを任意のコンポーネントに関連付ける必要はなく、リダイレクトは必要ありません。

+0

私はあなたの考えを持っていると思います。それを実装しようとします。 – ssuhat