React-router,JWT Cookie,Flux,Authentification& SSR

时间:2015-08-11 17:23:50

标签: reactjs server-side reactjs-flux react-router

Hello StackOverflow社区!

我的申请背景有点复杂,但我觉得我的问题不是。 所以我首次申请了一个由注册/登录/私有组件组成的应用程序。我的routes.js包含以下内容

// routes.js
function requireAuth(nextState, transition) {
  if (!LoginStore.isLoggedIn()) {
    transition.to('/login', null, { nextPathname: nextState.location.pathname });
  }
}
<Route component={require('./components/App')} >
  <Route path="/" component={require('./components/Home')} />
  <Route path="/login" component={require('./components/LogIn')} />
  <Route path="/signup" component={require('./components/SignUp')} />
  <Route path="/private" component={require('./components/Private')} onEnter={requireAuth}/>
</Route>

登录组件从API检索JWT,将其存储在LoginStore组件(Flux设计)和Cookie中,以便以后无需重新登录即可访问Private组件。 整个工作正常,因为当我登录时,我可以访问私有组件,我可以在刷新时访问它(感谢cookie)。

我的问题来自于我也在服务器上呈现此解决方案,如果我尝试直接访问/ private(直接我的意思是我的第一次调用应用程序是/ private),我被重定向到/登录然后我可以访问/ private。我想在第一次电话会议上/私人会员。

// server.js
var location = new Location(req.path, req.query);
  Router.run(routes, location, (error, initialState, transition) => {
    console.log(initialState);
      if (transition.isCancelled) {
        return res.redirect(302, transition.redirectInfo.pathname);
      } else {
        var html = React.renderToString(<Router {...initialState}/>);
        res.send(renderFullPage(html));
      }
  });

我的LoginStore应该检索cookie并允许访问私有组件但是他没有成功,因为我的cookie还没有找到。

GET http://localhost/private [HTTP/1.1 302 Moved Temporarily 30ms]
GET http://localhost/login [HTTP/1.1 200 OK 51ms]
GET http://localhost/bundle.js [HTTP/1.1 200 OK 30ms]

我觉得我应该将我的cookie发送到server.js中的路由器,这样可以设置LoginStore,但我不知道如何做到这一点,它可能不是最好的解决方案。我真的很感激这个问题的帮助。

提前谢谢你。

1 个答案:

答案 0 :(得分:2)

您的解决方案与我的解决方案类似。在调用react-cookie之前,使用Router.run在每个请求上操作服务器上的cookie和补丁保存/删除方法。还要确保您的路线同步。

import Iso from 'iso';
import React from 'react';
import ReactDomServer from 'react-dom/server';
import Router from 'react-router';
import Location from 'react-router/lib/Location';
import cookie from 'react-cookie';
import routes from '../../app/routes';
import Alt from '../../app/lib/Alt';
import AltBootstrap from '../lib/AltBootstrap';

export default {render};

function render(req, res, next) {
  cookie.setRawCookie(req.headers.cookie); // THIS
  cookie.save = res.cookie.bind(res); // THIS

  let location = new Location(req.path, req.query);
  Router.run(routes, location, (error, state, transition) => {
    if (error) return next(error);
    if (transition.isCancelled) return res.redirect(transition.redirectInfo.pathname);

    AltBootstrap.run(state, req).then(snapshot => {
      Alt.bootstrap(snapshot);

      let markup = ReactDomServer.renderToString(<Router {...state}/>);
      let html = Iso.render(markup, Alt.flush());
      res.render('index', {html});
    }).catch(next);
  });
}

此处提供了完整的源代码:isomorphic-react-flux-boilerplate