在身份验证模式中使用 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 处理程序的路由。

即发生的事情是:

  1. 路由器尝试处理对 / 的请求(/login 的第一个匹配项)。
  2. / 有一个 onEnter 处理程序。处理程序已执行。
  3. Handler 想要导航到 /login
  4. 路由器尝试处理对 / 的请求(返回步骤 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.

中提取的真实示例

如果这对您有帮助,请告诉我。