React-router、JWT Cookie、Flux、身份验证和 SSR
React-router, JWT Cookie, Flux, Authentification & SSR
Whosebug 社区您好!
我的申请背景有点复杂,但我觉得我的问题不是。
所以我有一个包含注册/登录/私有组件的应用程序的首次亮相。我的 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>
Log In 组件从 API JWT 检索,将其存储在 LoginStore 组件(Flux 设计)和 Cookie 中,以便以后无需重新登录即可访问 Private 组件。
整个工作正常,因为当我登录时,我可以访问私有组件,并且可以在刷新时访问它(多亏了 cookie)。
我的问题来自于我也在服务器上呈现这个解决方案,如果我尝试直接访问/private(直接我的意思是我对应用程序的第一次调用是/private),我被重定向到 /login 然后我可以访问 /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 并允许访问 Private 组件,但他没有成功,因为还找不到我的 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,但我不太了解如何做,这可能不是最好的解决方案。非常感谢能解决这个问题。
提前致谢。
您的解决方案与我的相似。在调用 Router.run
之前,使用 react-cookie
操作 cookie 并在服务器上对每个请求修补 save/delete 方法。还要确保您的路线同步。
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。
Whosebug 社区您好!
我的申请背景有点复杂,但我觉得我的问题不是。 所以我有一个包含注册/登录/私有组件的应用程序的首次亮相。我的 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>
Log In 组件从 API JWT 检索,将其存储在 LoginStore 组件(Flux 设计)和 Cookie 中,以便以后无需重新登录即可访问 Private 组件。 整个工作正常,因为当我登录时,我可以访问私有组件,并且可以在刷新时访问它(多亏了 cookie)。
我的问题来自于我也在服务器上呈现这个解决方案,如果我尝试直接访问/private(直接我的意思是我对应用程序的第一次调用是/private),我被重定向到 /login 然后我可以访问 /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 并允许访问 Private 组件,但他没有成功,因为还找不到我的 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,但我不太了解如何做,这可能不是最好的解决方案。非常感谢能解决这个问题。
提前致谢。
您的解决方案与我的相似。在调用 Router.run
之前,使用 react-cookie
操作 cookie 并在服务器上对每个请求修补 save/delete 方法。还要确保您的路线同步。
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。