2016-09-15 7 views
5

ユーザが認証されているかどうかをチェックし、そうでない場合は別のURLにリダイレクトする上位コンポーネントがあります。リダイレクトルータがサーバ上でリダイレクトしない

これは同形アプリですが、これはクライアント側で動作しますが、JSをオフにするとサーバーはリダイレクトされません。

if (!this.props.authenticated) { 
    this.context.router.push('/'); 
} 

私は、サーバー上でこの文を打つことができるとthis.context.routerは戻っているが、何も起こりません。

全コンポーネント:

import { RouterContext, match } from 'react-router'; 
import { Provider } from 'react-redux'; 
import { renderToString } from 'react-dom/server'; 
import React from 'react'; 
import reactCookie from 'react-cookie'; 

import configureStore from '../../shared/store'; 
import routes from '../../shared/routes'; 
import assets from '../../public/assets.json'; 

import { AUTH_USER } from '../../shared/actions/types'; 

export default function (req, res) { 
    match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { 
     if (error) return res.status(500).send(error.message); 
     if (redirectLocation) return res.redirect(302, redirectLocation.pathname + redirectLocation.search); 
     if (!renderProps) return res.status(404).send('Page not found'); 

     const store = configureStore(); 

     // use cookies to retrieve token 
     const unplug = reactCookie.plugToRequest(req, res); // eslint-disable-line no-unused-vars 
     const token = reactCookie.load('token'); 

     // if we have a token, consider the user to be signed in 
     if (token) { 
      // we need to update application state 
      store.dispatch({ type: AUTH_USER }); 
     } 

     const content = renderToString(
      <Provider store={store}> 
       <RouterContext {...renderProps} /> 
      </Provider> 
     ); 

     const initialState = JSON.stringify(store.getState()); 

     return res.render('index', { content, assets, initialState }); 
    }); 
} 
+0

JSをオフにしました。あなたはそれがどのように機能すると思いますか? – activatedgeek

+1

node.jsを使用した同形アプリ – Paul

答えて

1

、あなたのサーバーを共有できます。これは、サーバーコードがレンダリングされ

export default (
    <Route path='/' component={App}> 
     <IndexRoute component={Welcome} /> 
     <Route path='/feature' component={requireAuth(Feature)} /> 
     <Route path='/signin' component={Signin} /> 
     <Route path='/signout' component={Signout} /> 
     <Route path='/signup' component={Signup} /> 
    </Route> 
); 

import React, { Component, PropTypes } from 'react'; 
import { connect } from 'react-redux'; 

export default function (ComposedComponent) { 
    class Authentication extends Component { 
     static contextTypes = { 
      router: React.PropTypes.object 
     } 

     static propTypes = { 
      authenticated: PropTypes.bool 
     } 

     componentWillMount() { 
      if (!this.props.authenticated) { 
       this.context.router.push('/'); 
      } 
     } 

     componentWillUpdate(nextProps) { 
      if (!nextProps.authenticated) { 
       this.context.router.push('/'); 
      } 
     } 

     render() { 
      return <ComposedComponent {...this.props} />; 
     } 
    } 

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

    return connect(mapStateToProps)(Authentication); 
} 

と、このコンポーネントは、routesファイルを介して到達されますレンダリングコード?おそらくhttps://github.com/ReactTraining/react-router/blob/master/docs/guides/ServerRendering.mdのようなもので、redirectLocationフラグをチェックしている必要があります。そのredirectLocationは、ラッパーコンポーネントの代わりにonEnterフックを使用して返すことができます。 onEnterフックはhereと記載されています。

以下のコメントから更新してください:サーバーコードが正しくredirectLocationをチェックしていますが、ルーティングコードはフックを使用してredirectLocationを正しく設定する必要があります。これと同じように:

オクラホマので、そのように、フォーカス取得時のフックを使用して、あなたが正しく、サーバーコードでredirectLocationを尊重しているが、redirectLocationのみが読み込まれます。

const userIsInATeam = (nextState, replace) => { 
    if (!isAuth) { 
    replace('/') 
    } 
} 

<Route path="https://stackoverflow.com/users/:userId/teams" onEnter={userIsInATeam} /> 

私はnextStateが持つべきだと思うauthはあなたを支えますそれを確認して認証を確認しています。

+0

上記のサーバーコードを – Paul

+0

に追加しました。 –

+0

ありがとうございます - ルートに戻るように見えるようになりましたが、今度は2つの新しいエラーが発生します。 警告:失敗した小道具タイプ: 'Route'に無効な小道具 'children'が供給されました。 Router' と '警告で :[反応ルータ]ロケーション「/」は、任意のroutes'と一致しなかった – Paul