2016-09-15 136 views
5

我有一個高階組件,用於檢查用戶是否已通過身份驗證,如果沒有,則會重定向到其他網址。React路由器不在服務器上重定向

它是一個同構的應用程序,它適用於客戶端,但如果我關閉JS,服務器不會重定向。

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

我可以在服務器上打這一說法,並this.context.router逐漸復甦,但沒有任何反應。

全部組件:

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 { 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

你可以分享你的服務器

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); 
} 

,這部分是通過路由文件達到渲染代碼?它可能需要看起來像https://github.com/ReactTraining/react-router/blob/master/docs/guides/ServerRendering.md,你在檢查redirectLocation標誌。 redirectLocation可以通過使用onEnter鉤子而不是包裝器組件返回。 onEnter掛鉤記錄在here

更新從下面的評論:好,所以你的服務器代碼正確檢查redirectLocation,但路由代碼需要使用onEnter掛鉤來正確設置redirectLocation。像這樣:

好了,你要正確履行redirectLocation在服務器代碼,但只填充redirectLocation使用的OnEnter鉤,就像這樣:

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

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

我覺得nextState應該有auth道具你正在尋找它來檢查身份驗證。

+0

我已經添加了上面的服務器代碼 – Paul

+0

太好了,我更新了我的回答上面的迴應! –

+0

謝謝 - 現在看起來它的重定向回到根目錄,但是現在得到兩個新錯誤 '警告:失敗的道具類型:提供給'路線'的道具'子項'無效。 在Router' 和 '警告:[反應路由器]地址「/」沒有匹配的routes' – Paul