在身份验证模式中使用 react-router 时超出调用堆栈
Call stack exceeded when using react-router in an auth pattern
我在以下身份验证模式中使用 react-router rc6
:
const isLoggedIn = false
function requireAuth (nextState, replaceState) {
console.log(nextState.location.pathname)
if(!isLoggedIn) {
replaceState({ nextPathName: nextState.location.pathname }, '/login')
}
}
ReactDOM.render((
<Router history={browserHistory}>
<Route path='/' component={Main} onEnter={requireAuth}>
<Route path='login' component={Login} />
</Route>
</Router>
), document.getElementById('app'));
我认为这是一种常见模式,但根据 https://github.com/rackt/react-router/issues/2773,我无法在 onEnter
挂钩中重定向,因为上面的函数 requireAuth
在无限循环。我应该怎么做呢?如果未通过身份验证,我想重定向到 /login
页面。
这是因为 /
onEnter
处理程序试图重定向到执行相同 /
onEvent
处理程序的路由。
即发生的事情是:
- 路由器尝试处理对
/
的请求(/login
的第一个匹配项)。
/
有一个 onEnter
处理程序。处理程序已执行。
- Handler 想要导航到
/login
。
- 路由器尝试处理对
/
的请求(返回步骤 1)。
如您所见,您收到调用堆栈超出错误的原因是因为它是循环的。
尝试将您的路线更改为以下内容:
ReactDOM.render((
<Router history={browserHistory}>
<Route path='/' component={Main}>
<Route path='/login' component={Login} />
<Route path='/user' onEnter={requireAuth}>
<Route path='/profile' component={Profile}>
</Route>
</Route>
</Router>
), document.getElementById('app'));
这样只有需要身份验证的路由才能在您的 requireAuth
处理程序后面受到保护。
如果您想要一个简单的 React 身份验证解决方案,请查看我构建的 React SDK for Stormpath。
它会处理所有这些。而不是必须使用 hacky onEnter
处理程序,您需要做的就是使用 SDK 的 AuthenticatedRoute
。例如
<Router history={createBrowserHistory()}>
<HomeRoute path='/' component={MasterPage}>
<IndexRoute component={IndexPage} />
<LoginRoute path='/login' component={LoginPage} />
<LogoutRoute path='/logout' />
<Route path='/verify' component={VerifyEmailPage} />
<Route path='/register' component={RegisterPage} />
<Route path='/forgot' component={ResetPasswordPage} />
<AuthenticatedRoute>
<HomeRoute path='/profile' component={ProfilePage} />
</AuthenticatedRoute>
</HomeRoute>
</Router>
以上示例是从 React SDK example project. See: https://github.com/stormpath/stormpath-express-react-example/blob/master/src/app.js#L11-L23.
中提取的真实示例
如果这对您有帮助,请告诉我。
我在以下身份验证模式中使用 react-router rc6
:
const isLoggedIn = false
function requireAuth (nextState, replaceState) {
console.log(nextState.location.pathname)
if(!isLoggedIn) {
replaceState({ nextPathName: nextState.location.pathname }, '/login')
}
}
ReactDOM.render((
<Router history={browserHistory}>
<Route path='/' component={Main} onEnter={requireAuth}>
<Route path='login' component={Login} />
</Route>
</Router>
), document.getElementById('app'));
我认为这是一种常见模式,但根据 https://github.com/rackt/react-router/issues/2773,我无法在 onEnter
挂钩中重定向,因为上面的函数 requireAuth
在无限循环。我应该怎么做呢?如果未通过身份验证,我想重定向到 /login
页面。
这是因为 /
onEnter
处理程序试图重定向到执行相同 /
onEvent
处理程序的路由。
即发生的事情是:
- 路由器尝试处理对
/
的请求(/login
的第一个匹配项)。 /
有一个onEnter
处理程序。处理程序已执行。- Handler 想要导航到
/login
。 - 路由器尝试处理对
/
的请求(返回步骤 1)。
如您所见,您收到调用堆栈超出错误的原因是因为它是循环的。
尝试将您的路线更改为以下内容:
ReactDOM.render((
<Router history={browserHistory}>
<Route path='/' component={Main}>
<Route path='/login' component={Login} />
<Route path='/user' onEnter={requireAuth}>
<Route path='/profile' component={Profile}>
</Route>
</Route>
</Router>
), document.getElementById('app'));
这样只有需要身份验证的路由才能在您的 requireAuth
处理程序后面受到保护。
如果您想要一个简单的 React 身份验证解决方案,请查看我构建的 React SDK for Stormpath。
它会处理所有这些。而不是必须使用 hacky onEnter
处理程序,您需要做的就是使用 SDK 的 AuthenticatedRoute
。例如
<Router history={createBrowserHistory()}>
<HomeRoute path='/' component={MasterPage}>
<IndexRoute component={IndexPage} />
<LoginRoute path='/login' component={LoginPage} />
<LogoutRoute path='/logout' />
<Route path='/verify' component={VerifyEmailPage} />
<Route path='/register' component={RegisterPage} />
<Route path='/forgot' component={ResetPasswordPage} />
<AuthenticatedRoute>
<HomeRoute path='/profile' component={ProfilePage} />
</AuthenticatedRoute>
</HomeRoute>
</Router>
以上示例是从 React SDK example project. See: https://github.com/stormpath/stormpath-express-react-example/blob/master/src/app.js#L11-L23.
中提取的真实示例如果这对您有帮助,请告诉我。