【问题标题】:Handling firebase auth with react-router使用 react-router 处理 firebase 身份验证
【发布时间】:2017-01-13 07:55:03
【问题描述】:

我正在使用 webpack 构建一个 React + Redux + Firebase 应用程序,并试图找出处理受保护路由和重定向的最佳方法。我尝试过将onEnter()setTimeout() 一起使用,就像许多示例所示,但它仍然在重定向之前闪烁备用组件。

这是我目前拥有的,我正在尝试提出一个更优雅的解决方案。这主要是有效的,但是如果我在/profile 上并在浏览器中导航到/,则失败的一个例子。似乎因为firebase.auth() 需要再次初始化,所以在切换到Profile 之前,我得到了HomePage 组件的闪光。

Firebase 在firebaseClientConfig 中初始化,我将firebase.auth() 传递给routes

import { auth } from './firebaseClientConfig';  

...    

export default (
<Route path="/" component={App}>    
 <IndexRoute
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (!user) {
        return require.ensure([], require => {
          cb(null, require('./components/HomePage').default);
        });
      } else {
        return require.ensure([], require => {
          cb(null, require('./modules/Profile/Profile').default);
        });
      }
    });
  }}
/>
<Route
  path="/profile"
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (user) {
        return require.ensure([], require => {
          cb(null, require('./modules/Profile/Profile').default);
        });
      } else {
        return require.ensure([], require => {
          cb(null, require('./modules/Login/Login').default);
        });
      }
    });
  }}
/>
</Route>
);

有人有更好的方法吗?

【问题讨论】:

  • 这很优雅,不错!
  • @Bonitis 我听说 redux 不适合 firebase
  • @Ezeewei 他们实际上合作得很好!这个问题已经过时了,因为 react-router 已经从 v3 -> v4 走了,所以有很大的变化。总的来说,我对 redux+firebase 没有任何问题。
  • @Bonitis 不错!这是一个非常好的消息,我自己正在犹豫将它们整合在一起。谢谢!

标签: javascript reactjs firebase react-router firebase-authentication


【解决方案1】:

我制作了一个PrivateRoute 组件并传递给它一个authenticated 道具,我从我使用PrivateRoute 的组件中的redux 商店获得该道具

当我使用 firebase 登录时,我将用户数据放入 redux 存储中。所以在我的情况下,我会将状态映射到道具

const mapStateToProps = (state) => ({
    authenticated: !!state.user.uid,
})

并将经过身份验证的道具提供给我的PrivateRoute 组件

const PrivateRoute = ({ component: Component, authenticated, path, exact }) => {
  return (
      <Route
          path={path}
          exact={exact}
          render={props =>
            authenticated
              ? <Component {...props} />
              : <Redirect to="/login"/>}
        />
    )
}

【讨论】:

  • 登录后刷新会发生什么?我的看起来和你的相似,但我发现我被重定向到一个新页面
  • 正确使用 redux 和中间件,firebase 应该跟踪您的身份验证状态。
【解决方案2】:

如果您使用本地状态而不是 redux 来管理身份验证,那么您需要创建两个状态来保存您的身份验证进度。

state={"loading=true",
"loggedin=false"}

即redner 在 loading 为真时加载组件,当我从 firebase 函数接收当前用户状态时,我将使用 setState() 将加载设置为 flase 并根据用户状态进一步渲染我打算渲染的组件。

为了更好地理解,请查看react firebase authentication

【讨论】:

    【解决方案3】:

    我知道有点晚了,但这可能对其他人有所帮助:您可以找到一种稍微不同的方法here(仍然使用类似于 vhflat 的私有路由,但我发现它更清晰且易于实现)。

    基本上,在您的私人路线中,您只需

    import { useSelector } from "react-redux";
    

    import { isLoaded } from 'react-redux-firebase'
    

    之后你得到这样的身份验证

    const auth = useSelector( state => state.firebase.auth );
    

    然后,如果isLoaded( auth ) 不正确(因此未加载身份验证状态),您可以重定向到加载页面,或者如果您不想返回&lt;React.Fragment&gt;&lt;/React.Fragment&gt;

    最后,如果你返回,你可以检查是否!isEmpty( auth ),如果是则返回子组件,否则重定向到登录页面或你喜欢的任何其他页面。

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 2019-04-11
      • 2017-02-14
      • 1970-01-01
      • 2016-06-12
      • 2018-10-21
      • 2020-12-23
      • 1970-01-01
      • 2021-07-11
      相关资源
      最近更新 更多